diff --git a/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/MaxParallelDownloadsTests.cs b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/MaxParallelDownloadsTests.cs new file mode 100644 index 00000000000..d9ae89ef0c6 --- /dev/null +++ b/src/mono/wasm/Wasm.Build.Tests/TestAppScenarios/MaxParallelDownloadsTests.cs @@ -0,0 +1,48 @@ +// 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.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Xunit.Abstractions; +using System.Text.RegularExpressions; +using Xunit; + +#nullable enable + +namespace Wasm.Build.Tests.TestAppScenarios; + +public class MaxParallelDownloadsTests : AppTestBase +{ + public MaxParallelDownloadsTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) + : base(output, buildContext) + { + } + + [Theory] + [InlineData("Release", "1")] + [InlineData("Release", "4")] + public async Task NeverFetchMoreThanMaxAllowed(string config, string maxParallelDownloads) + { + CopyTestAsset("WasmBasicTestApp", "MaxParallelDownloadsTests", "App"); + BuildProject(config); + + var result = await RunSdkStyleAppForBuild(new( + Configuration: config, + TestScenario: "MaxParallelDownloads", + BrowserQueryString: new Dictionary { ["maxParallelDownloads"] = maxParallelDownloads } + )); + var resultTestOutput = result.TestOutput.ToList(); + var regex = new Regex(@"Active downloads: (\d+)"); + foreach (var line in resultTestOutput) + { + var match = regex.Match(line); + if (match.Success) + { + int activeDownloads = int.Parse(match.Groups[1].Value); + Assert.True(activeDownloads <= int.Parse(maxParallelDownloads), $"Active downloads exceeded the limit: {activeDownloads} > {maxParallelDownloads}"); + } + } + } +} diff --git a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js index 21cc18cc3e7..0023e28f4c3 100644 --- a/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js +++ b/src/mono/wasm/testassets/WasmBasicTestApp/App/wwwroot/main.js @@ -93,6 +93,26 @@ switch (testCase) { await dotnet.download(); testOutput("download finished"); break; + case "MaxParallelDownloads": + const maxParallelDownloads = params.get("maxParallelDownloads"); + let activeFetchCount = 0; + const originalFetch2 = globalThis.fetch; + globalThis.fetch = async (...args) => { + activeFetchCount++; + testOutput(`Fetch started. Active downloads: ${activeFetchCount}`); + try { + const response = await originalFetch2(...args); + activeFetchCount--; + testOutput(`Fetch completed. Active downloads: ${activeFetchCount}`); + return response; + } catch (error) { + activeFetchCount--; + testOutput(`Fetch failed. Active downloads: ${activeFetchCount}`); + throw error; + } + }; + dotnet.withConfig({ maxParallelDownloads: maxParallelDownloads }); + break; } const { setModuleImports, getAssemblyExports, getConfig, INTERNAL } = await dotnet.create(); @@ -145,6 +165,7 @@ try { exit(0); break; case "DownloadThenInit": + case "MaxParallelDownloads": exit(0); break; default: