-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[browser] Allow download retry+throttling in unified code with blazor #88910
Changes from all commits
919fc99
f7c2976
1dc2aad
570272d
71269b3
cfda22f
aef0bd6
622e2de
62b577a
d93f5bf
f653b0a
989ee2c
8f38e65
2265d4e
ac278a5
d217786
eb8c3e0
31a800f
8866516
b902090
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// 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.IO; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using Xunit; | ||
using Xunit.Abstractions; | ||
|
||
#nullable enable | ||
|
||
namespace Wasm.Build.Tests.TestAppScenarios; | ||
|
||
public class DownloadResourceProgressTests : AppTestBase | ||
{ | ||
public DownloadResourceProgressTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) | ||
: base(output, buildContext) | ||
{ | ||
} | ||
|
||
[Theory] | ||
[InlineData(false)] | ||
[InlineData(true)] | ||
public async Task DownloadProgressFinishes(bool failAssemblyDownload) | ||
{ | ||
CopyTestAsset("WasmBasicTestApp", $"DownloadResourceProgressTests_{failAssemblyDownload}"); | ||
PublishProject("Debug"); | ||
|
||
var result = await RunSdkStyleApp(new( | ||
Configuration: "Debug", | ||
ForPublish: true, | ||
TestScenario: "DownloadResourceProgressTest", | ||
BrowserQueryString: new Dictionary<string, string> { ["failAssemblyDownload"] = failAssemblyDownload.ToString().ToLowerInvariant() } | ||
)); | ||
Assert.True( | ||
result.TestOutput.Any(m => m.Contains("DownloadResourceProgress: Finished")), | ||
"The download progress test didn't emit expected error message" | ||
); | ||
Assert.True( | ||
result.ConsoleOutput.Any(m => m.Contains("Retrying download")) == failAssemblyDownload, | ||
failAssemblyDownload | ||
? "The download progress test didn't emit expected message about retrying download" | ||
: "The download progress test did emit unexpected message about retrying download" | ||
); | ||
Assert.False( | ||
result.ConsoleOutput.Any(m => m.Contains("Retrying download (2)")), | ||
"The download progress test did emit unexpected message about second download retry" | ||
); | ||
Assert.True( | ||
result.TestOutput.Any(m => m.Contains("Throw error instead of downloading resource") == failAssemblyDownload), | ||
failAssemblyDownload | ||
? "The download progress test didn't emit expected message about failing download" | ||
: "The download progress test did emit unexpected message about failing download" | ||
); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,10 @@ if (testCase == null) { | |
exit(2, new Error("Missing test scenario. Supply query argument 'test'.")); | ||
} | ||
|
||
function testOutput(msg) { | ||
console.log(`TestOutput -> ${msg}`); | ||
} | ||
|
||
// Prepare base runtime parameters | ||
dotnet | ||
.withElementOnExit() | ||
|
@@ -21,6 +25,37 @@ switch (testCase) { | |
case "AppSettingsTest": | ||
dotnet.withApplicationEnvironment(params.get("applicationEnvironment")); | ||
break; | ||
case "DownloadResourceProgressTest": | ||
if (params.get("failAssemblyDownload") === "true") { | ||
let assemblyCounter = 0; | ||
let failAtAssemblyNumbers = [ | ||
Math.floor(Math.random() * 5), | ||
Math.floor(Math.random() * 5) + 5, | ||
Math.floor(Math.random() * 5) + 10 | ||
maraf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
]; | ||
dotnet.withDiagnosticTracing(true).withResourceLoader((type, name, defaultUri, integrity) => { | ||
if (type !== "assembly") | ||
return defaultUri; | ||
|
||
assemblyCounter++; | ||
if (!failAtAssemblyNumbers.includes(assemblyCounter)) | ||
return defaultUri; | ||
|
||
testOutput("Throw error instead of downloading resource"); | ||
maraf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const error = new Error("Simulating a failed fetch"); | ||
error.silent = true; | ||
throw error; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this get surfaced to the user at all? What behavior does blazor have when we fail to load an assembly at all? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before this PR, the Blazor aborts on first download failure. Their original approach was to let the user override There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant, is this surfaced when even a 3rd retry fails? |
||
}); | ||
} | ||
dotnet.withModuleConfig({ | ||
onDownloadResourceProgress: (loaded, total) => { | ||
console.log(`DownloadResourceProgress: ${loaded} / ${total}`); | ||
if (loaded === total && loaded !== 0) { | ||
testOutput("DownloadResourceProgress: Finished"); | ||
} | ||
} | ||
}); | ||
break; | ||
} | ||
|
||
const { getAssemblyExports, getConfig, INTERNAL } = await dotnet.create(); | ||
|
@@ -48,9 +83,13 @@ try { | |
exports.AppSettingsTest.Run(); | ||
exit(0); | ||
break; | ||
case "DownloadResourceProgressTest": | ||
exit(0); | ||
break; | ||
default: | ||
console.error(`Unknown test case: ${testCase}`); | ||
exit(3); | ||
break; | ||
} | ||
} catch (e) { | ||
exit(1, e); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename to indicate that this is testing retries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(intended) Retry happens only when
failAssemblyDownload=true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, and that's what we are testing here :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are testing "download progress" counter, one case is with retry and one is without