diff --git a/docs/workflow/testing/libraries/testing-wasm.md b/docs/workflow/testing/libraries/testing-wasm.md index a8d7eb1a7934d..58b4a971d0a1f 100644 --- a/docs/workflow/testing/libraries/testing-wasm.md +++ b/docs/workflow/testing/libraries/testing-wasm.md @@ -100,12 +100,15 @@ 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-env"` -> becomes `dotnet xharness wasm test --set-web-server-env` - `$(WasmXHarnessMonoArgs)` - arguments to mono Example: `WasmXHarnessMonoArgs="--runtime-arg=--trace=E"` +- `$(WasmXHarnessMonoArgs)` - env variables to mono + Example: `WasmXHarnessMonoArgs="--setenv=MONO_LOG_LEVEL=debug"` + - `$(WasmTestAppArgs)` - arguments for the test app itself ### Running outer loop tests using Browser instance diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/GenericHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/GenericHandler.cs new file mode 100644 index 0000000000000..0ab060eeef702 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/GenericHandler.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; + +namespace MonoNetTestServer +{ + public class GenericHandler + { + RequestDelegate next; + public GenericHandler(RequestDelegate next) + { + this.next = next; + } + + public async Task Invoke(HttpContext context) + { + PathString path = context.Request.Path; + if (path.Equals(new PathString("/remoteLoop"))) + { + await RemoteLoopHandler.InvokeAsync(context); + return; + } + + await next(context); + } + } + + public static class GenericHandlerExtensions + { + public static IApplicationBuilder UseGenericHandler(this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + + public static void SetStatusDescription(this HttpResponse response, string description) + { + response.HttpContext.Features.Get().ReasonPhrase = description; + } + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Handlers/RemoteLoopHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Handlers/RemoteLoopHandler.cs new file mode 100644 index 0000000000000..c8a2d14b02da1 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Handlers/RemoteLoopHandler.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Net; +using System.Net.Sockets; +using System.Net.WebSockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace MonoNetTestServer +{ + public class RemoteLoopHandler + { + private const int MaxBufferSize = 128 * 1024; + + public static async Task InvokeAsync(HttpContext context) + { + try + { + if (!context.WebSockets.IsWebSocketRequest) + { + context.Response.StatusCode = 400; + context.Response.ContentType = "text/plain"; + await context.Response.WriteAsync("Not a websocket request"); + + return; + } + + using (WebSocket socket = await context.WebSockets.AcceptWebSocketAsync()) + { + await ProcessWebSocketRequest(context, socket); + } + + } + catch (Exception) + { + // We might want to log these exceptions. But for now we ignore them. + } + } + + enum CommandType + { + Listen, + Open, + Send, + Receive, + Close + } + + class Command + { + public CommandType Type { get; set; } + public byte[] Data { get; set; } + public int Port { get; set; } + public int ListenBacklog { get; set; } + public IPAddress Address { get; set; } + } + + private static async Task ProcessWebSocketRequest(HttpContext context, WebSocket webSocket) + { + Socket listenSocket = null; + Socket current = null; + Memory ms = new Memory(); + + ValueWebSocketReceiveResult result = await webSocket.ReceiveAsync(ms, CancellationToken.None); + while (result.MessageType != WebSocketMessageType.Close) + { + Command command = null; // get bytes=> json=>command + switch (command.Type) + { + case CommandType.Listen: + listenSocket = new Socket(command.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + listenSocket.Bind(new IPEndPoint(command.Address, 0)); + listenSocket.Listen(command.ListenBacklog); + break; + case CommandType.Open: + current = await listenSocket.AcceptAsync().ConfigureAwait(false); + break; + case CommandType.Close: + current.Close(); + break; + } + + result = await webSocket.ReceiveAsync(ms, CancellationToken.None); + } + await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "closing remoteLoop", CancellationToken.None); + + } + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/MonoNetTestServer.csproj b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/MonoNetTestServer.csproj new file mode 100644 index 0000000000000..ecea6bb41ec09 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/MonoNetTestServer.csproj @@ -0,0 +1,20 @@ + + + + net5.0 + InProcess + Exe + false + + + + + + + + + + + + + diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Program.cs b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Program.cs new file mode 100644 index 0000000000000..e1c1aea87dcd2 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Program.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + +namespace MonoNetTestServer +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Startup.cs b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Startup.cs new file mode 100644 index 0000000000000..f7ba80ef901ba --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/Startup.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; + +namespace MonoNetTestServer +{ + public class Startup + { + public void ConfigureServices(IServiceCollection services) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + app.UseWebSockets(); + app.UseGenericHandler(); + } + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.Development.json b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.Development.json new file mode 100644 index 0000000000000..e203e9407e74a --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.json b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.json new file mode 100644 index 0000000000000..def9159a7d940 --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/MonoNetTestServer/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer.sln b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer.sln deleted file mode 100644 index 8e5d44de5cd87..0000000000000 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.438 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetCoreServer", "NetCoreServer\NetCoreServer.csproj", "{86E9A13D-9F4A-45DE-B0BB-CBB6A6533867}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {86E9A13D-9F4A-45DE-B0BB-CBB6A6533867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {86E9A13D-9F4A-45DE-B0BB-CBB6A6533867}.Debug|Any CPU.Build.0 = Debug|Any CPU - {86E9A13D-9F4A-45DE-B0BB-CBB6A6533867}.Release|Any CPU.ActiveCfg = Release|Any CPU - {86E9A13D-9F4A-45DE-B0BB-CBB6A6533867}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {2F9A0637-452E-4FB9-9403-CB52944982DA} - EndGlobalSection -EndGlobal diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/GenericHandler.cs b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/GenericHandler.cs index 6efc71033a308..f129157b1d916 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/GenericHandler.cs +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/GenericHandler.cs @@ -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) diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj index d9b272d4d3241..ae85a480aec8b 100644 --- a/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetCoreServer/NetCoreServer.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net5.0 InProcess Exe false diff --git a/src/libraries/Common/tests/System/Net/Prerequisites/NetTestServers.sln b/src/libraries/Common/tests/System/Net/Prerequisites/NetTestServers.sln new file mode 100644 index 0000000000000..e7a89164d089c --- /dev/null +++ b/src/libraries/Common/tests/System/Net/Prerequisites/NetTestServers.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31229.75 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoNetTestServer", "MonoNetTestServer\MonoNetTestServer.csproj", "{86E9A13D-9F4A-45DE-B0BB-CBB6A6533868}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetCoreServer", "NetCoreServer\NetCoreServer.csproj", "{2BB687CC-3F0C-43A9-8F38-140E91892EB0}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {86E9A13D-9F4A-45DE-B0BB-CBB6A6533868}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86E9A13D-9F4A-45DE-B0BB-CBB6A6533868}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86E9A13D-9F4A-45DE-B0BB-CBB6A6533868}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86E9A13D-9F4A-45DE-B0BB-CBB6A6533868}.Release|Any CPU.Build.0 = Release|Any CPU + {2BB687CC-3F0C-43A9-8F38-140E91892EB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2BB687CC-3F0C-43A9-8F38-140E91892EB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2BB687CC-3F0C-43A9-8F38-140E91892EB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2BB687CC-3F0C-43A9-8F38-140E91892EB0}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2F9A0637-452E-4FB9-9403-CB52944982DA} + EndGlobalSection +EndGlobal diff --git a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj index 21ba2a12dd524..85f7ad2446ed1 100644 --- a/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj +++ b/src/libraries/System.Net.WebSockets.Client/tests/System.Net.WebSockets.Client.Tests.csproj @@ -3,36 +3,26 @@ ../src/Resources/Strings.resx $(NetCoreAppCurrent);$(NetCoreAppCurrent)-Browser $(DefineConstants);NETSTANDARD + WasmTestOnBrowser + $(WasmXHarnessArgs) --set-web-server-env --web-server-middleware=$(ArtifactsDir)bin/MonoNetTestServer/net5.0-$(Configuration)/MonoNetTestServer.dll --web-server-middleware=$(ArtifactsDir)bin/NetCoreServer/net5.0-$(Configuration)/NetCoreServer.dll - - - - - - - - - - - - + + + + + + + + + + + + @@ -51,4 +41,10 @@ + + +