Skip to content

Commit

Permalink
[wasm][testing] hosting echo server in xharness process (#52923)
Browse files Browse the repository at this point in the history
- move tests to inner loop
- include echo middleware in xharness server
- improve doc
- more granular ActiveIssue #53592 for lack of TRACE
- more granular ActiveIssue #53591 for content on GET/HEAD
- more granular ActiveIssue #53874 for HttpRequestMessage.Headers.Host
- more granular ActiveIssue #53872 for NPE on System.Net.Http.BrowserHttpHandler
- more granular ActiveIssue #53876
- include middleware in Helix correlation payload
  • Loading branch information
pavelsavara committed Jun 9, 2021
1 parent 78579ef commit fb61be4
Show file tree
Hide file tree
Showing 20 changed files with 202 additions and 122 deletions.
6 changes: 3 additions & 3 deletions docs/workflow/testing/libraries/testing-wasm.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,11 @@ The following shows how to run tests for a specific library

- `$(WasmXHarnessArgs)` - xharness command arguments

Example: `WasmXHarnessArgs="--xyz"` -> becomes `dotnet xharness wasm test --xyz`
Example: `WasmXHarnessArgs="--set-web-server-http-env=DOTNET_TEST_WEBSOCKETHOST"` -> becomes `dotnet xharness wasm test --set-web-server-http-env=DOTNET_TEST_WEBSOCKETHOST`

- `$(WasmXHarnessMonoArgs)` - arguments to mono
- `$(WasmXHarnessMonoArgs)` - arguments and variables for mono

Example: `WasmXHarnessMonoArgs="--runtime-arg=--trace=E"`
Example: `WasmXHarnessMonoArgs="--runtime-arg=--trace=E --setenv=MONO_LOG_LEVEL=debug"`

- `$(WasmTestAppArgs)` - arguments for the test app itself

Expand Down
5 changes: 3 additions & 2 deletions src/libraries/Common/tests/System/Net/Configuration.Http.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ public static partial class Http
{
private static readonly string DefaultHttp2AzureServer = "corefx-net-http2.azurewebsites.net";

// for the local server hosted in XHarness we are passing also port as part of the environment variables, because it's bound to random port number
public static string Host => GetValue("DOTNET_TEST_HTTPHOST", DefaultAzureServer);

public static string SecureHost => GetValue("DOTNET_TEST_SECUREHTTPHOST", DefaultAzureServer);

public static string Http2Host => GetValue("DOTNET_TEST_HTTP2HOST", DefaultHttp2AzureServer);
public static int Port = GetPortValue("DOTNET_TEST_HTTPHOST", 80);
public static int SecurePort = GetPortValue("DOTNET_TEST_SECUREHTTPHOST", 443);

// This server doesn't use HTTP/2 server push (push promise) feature. Some HttpClient implementations
// don't support servers that use push right now.
Expand Down
19 changes: 19 additions & 0 deletions src/libraries/Common/tests/System/Net/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ private static string GetValue(string envName, string defaultValue=null)
return Environment.ExpandEnvironmentVariables(envValue);
}

private static int GetPortValue(string envName, int defaultValue)
{
string envValue = Environment.GetEnvironmentVariable(envName);

if (string.IsNullOrWhiteSpace(envValue))
{
return defaultValue;
}
envValue = Environment.ExpandEnvironmentVariables(envValue);

var split = envValue.Split(':');
if (split.Length<2)
{
return defaultValue;
}

return int.Parse(split[1]);
}

private static Uri GetUriValue(string envName, Uri defaultValue=null)
{
string envValue = GetValue(envName, null);
Expand Down

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions src/libraries/Common/tests/System/Net/Http/PostScenarioTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public abstract class PostScenarioTest : HttpClientHandlerTestBase
public PostScenarioTest(ITestOutputHelper output) : base(output) { }

#if !NETFRAMEWORK
[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySent(Configuration.Http.RemoteServer remoteServer)
{
const string requestBody = "ABC";
Expand All @@ -53,17 +53,17 @@ public async Task PostRewindableStreamContentMultipleTimes_StreamContentFullySen
}
#endif

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[MemberData(nameof(RemoteServersMemberData))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupportedOrNotBrowser))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostNoContentUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer)
{
await PostHelper(remoteServer, string.Empty, null,
useContentLengthUpload: true, useChunkedEncodingUpload: false);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostEmptyContentUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -72,7 +72,7 @@ public async Task PostEmptyContentUsingContentLengthSemantics_Success(Configurat
useContentLengthUpload: true, useChunkedEncodingUpload: false);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostEmptyContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -81,7 +81,7 @@ public async Task PostEmptyContentUsingChunkedEncoding_Success(Configuration.Htt
useContentLengthUpload: false, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostEmptyContentUsingConflictingSemantics_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -90,7 +90,7 @@ public async Task PostEmptyContentUsingConflictingSemantics_Success(Configuratio
useContentLengthUpload: true, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostUsingContentLengthSemantics_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -99,7 +99,7 @@ public async Task PostUsingContentLengthSemantics_Success(Configuration.Http.Rem
useContentLengthUpload: true, useChunkedEncodingUpload: false);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -108,7 +108,7 @@ public async Task PostUsingChunkedEncoding_Success(Configuration.Http.RemoteServ
useContentLengthUpload: false, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostSyncBlockingContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -117,7 +117,7 @@ public async Task PostSyncBlockingContentUsingChunkedEncoding_Success(Configurat
useContentLengthUpload: false, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostRepeatedFlushContentUsingChunkedEncoding_Success(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -126,7 +126,7 @@ public async Task PostRepeatedFlushContentUsingChunkedEncoding_Success(Configura
useContentLengthUpload: false, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostUsingUsingConflictingSemantics_UsesChunkedSemantics(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -135,7 +135,7 @@ public async Task PostUsingUsingConflictingSemantics_UsesChunkedSemantics(Config
useContentLengthUpload: true, useChunkedEncodingUpload: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostUsingNoSpecifiedSemantics_UsesChunkedSemantics(Configuration.Http.RemoteServer remoteServer)
Expand All @@ -154,7 +154,7 @@ public static IEnumerable<object[]> RemoteServersAndLargeContentSizes()
}
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory]
[MemberData(nameof(RemoteServersAndLargeContentSizes))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
Expand Down Expand Up @@ -223,10 +223,10 @@ public async Task PostNonRewindableContentUsingAuth_PreAuthenticate_Success(Conf
await PostUsingAuthHelper(remoteServer, ExpectedContent, content, credential, preAuthenticate: true);
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[MemberData(nameof(RemoteServersMemberData))]
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsBrowserDomSupportedOrNotBrowser))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task PostAsync_EmptyContent_ContentTypeHeaderNotSent(Configuration.Http.RemoteServer remoteServer)
{
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer))
Expand Down
18 changes: 8 additions & 10 deletions src/libraries/Common/tests/System/Net/Http/ResponseStreamTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public static IEnumerable<object[]> RemoteServersAndReadModes()
}

}
[OuterLoop("Uses external servers")]

[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersAndReadModes))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
public async Task GetStreamAsync_ReadToEnd_Success(Configuration.Http.RemoteServer remoteServer, int readMode)
{
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer))
Expand Down Expand Up @@ -126,9 +126,9 @@ public async Task GetStreamAsync_ReadToEnd_Success(Configuration.Http.RemoteServ
}
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task GetAsync_UseResponseHeadersReadAndCallLoadIntoBuffer_Success(Configuration.Http.RemoteServer remoteServer)
{
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer))
Expand All @@ -146,9 +146,9 @@ public async Task GetAsync_UseResponseHeadersReadAndCallLoadIntoBuffer_Success(C
}
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)]
public async Task GetAsync_UseResponseHeadersReadAndCopyToMemoryStream_Success(Configuration.Http.RemoteServer remoteServer)
{
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer))
Expand All @@ -171,9 +171,8 @@ public async Task GetAsync_UseResponseHeadersReadAndCopyToMemoryStream_Success(C
}
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
public async Task GetStreamAsync_ReadZeroBytes_Success(Configuration.Http.RemoteServer remoteServer)
{
using (HttpClient client = CreateHttpClientForRemoteServer(remoteServer))
Expand All @@ -187,9 +186,8 @@ public async Task GetStreamAsync_ReadZeroBytes_Success(Configuration.Http.Remote
}
}

[OuterLoop("Uses external servers")]
[OuterLoop("Uses external servers", typeof(PlatformDetection), nameof(PlatformDetection.LocalEchoServerIsNotAvailable))]
[Theory, MemberData(nameof(RemoteServersMemberData))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/53018", TestPlatforms.Browser)]
public async Task ReadAsStreamAsync_Cancel_TaskIsCanceled(Configuration.Http.RemoteServer remoteServer)
{
var cts = new CancellationTokenSource();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project>
<PropertyGroup Condition="'$(TargetOS)' == 'Browser'">
<Scenario>WasmTestOnBrowser</Scenario>
<TestArchiveTestsRoot>$(TestArchiveRoot)browseronly/</TestArchiveTestsRoot>
<TestArchiveTestsDir>$(TestArchiveTestsRoot)$(OSPlatformConfig)/</TestArchiveTestsDir>

<!-- handle different path to middleware in Helix -->
<_TestEchoMiddleware Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(OS)' == 'Windows_NT'">%HELIX_CORRELATION_PAYLOAD%/xharness/TestEchoMiddleware</_TestEchoMiddleware>
<_TestEchoMiddleware Condition="'$(ContinuousIntegrationBuild)' == 'true' and '$(OS)' != 'Windows_NT'">$HELIX_CORRELATION_PAYLOAD/xharness/TestEchoMiddleware</_TestEchoMiddleware>
<_TestEchoMiddleware Condition="'$(ContinuousIntegrationBuild)' != 'true'">$(ArtifactsDir)bin/NetCoreServer/$(NetCoreAppCurrent)-$(Configuration)</_TestEchoMiddleware>

<WasmXHarnessArgs>$(WasmXHarnessArgs) --web-server-use-cors --web-server-use-https</WasmXHarnessArgs>
<WasmXHarnessArgs>$(WasmXHarnessArgs) --set-web-server-http-env=DOTNET_TEST_WEBSOCKETHOST,DOTNET_TEST_HTTPHOST</WasmXHarnessArgs>
<WasmXHarnessArgs>$(WasmXHarnessArgs) --set-web-server-https-env=DOTNET_TEST_SECUREWEBSOCKETHOST,DOTNET_TEST_SECUREHTTPHOST,DOTNET_TEST_HTTP2HOST</WasmXHarnessArgs>
<WasmXHarnessArgs>$(WasmXHarnessArgs) --web-server-middleware=$(_TestEchoMiddleware)/NetCoreServer.dll,GenericHandler</WasmXHarnessArgs>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class GenericHandler
// Must have constructor with this signature, otherwise exception at run time.
public GenericHandler(RequestDelegate next)
{
// This is an HTTP Handler, so no need to store next.
// This catch all HTTP Handler, so no need to store next.
}

public async Task Invoke(HttpContext context)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>$(AspNetCoreAppCurrent)</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<OutputType>Exe</OutputType>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,20 @@ public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(o => o.AddPolicy("AnyCors", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("*")
;
}));
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("AnyCors");
app.UseWebSockets();
app.UseGenericHandler();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using Microsoft.Win32;
using Xunit;

namespace System
{
Expand Down Expand Up @@ -59,6 +60,8 @@ public static partial class PlatformDetection
public static bool IsBrowserDomSupported => GetIsBrowserDomSupported();
public static bool IsBrowserDomSupportedOrNotBrowser => IsNotBrowser || GetIsBrowserDomSupported();
public static bool IsNotBrowserDomSupported => !IsBrowserDomSupported;
public static bool LocalEchoServerIsNotAvailable => !LocalEchoServerIsAvailable;
public static bool LocalEchoServerIsAvailable => IsBrowser;

public static bool IsUsingLimitedCultures => !IsNotMobile;
public static bool IsNotUsingLimitedCultures => IsNotMobile;
Expand Down
Loading

0 comments on commit fb61be4

Please sign in to comment.