From b43c6501ff9aaf730deef450973aecfd140661aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Thu, 24 Apr 2025 15:16:18 +0200 Subject: [PATCH 1/4] Remove the check for cacheBootResources --- src/Components/Web.JS/src/Services/WebRootComponentManager.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Components/Web.JS/src/Services/WebRootComponentManager.ts b/src/Components/Web.JS/src/Services/WebRootComponentManager.ts index 097a38c3e057..1c1dbb067db0 100644 --- a/src/Components/Web.JS/src/Services/WebRootComponentManager.ts +++ b/src/Components/Web.JS/src/Services/WebRootComponentManager.ts @@ -470,10 +470,6 @@ function isDescriptorInDocument(descriptor: ComponentDescriptor): boolean { } function areWebAssemblyResourcesLikelyCached(config: MonoConfig): boolean { - if (!config.cacheBootResources) { - return false; - } - const hash = getWebAssemblyResourceHash(config); if (!hash) { return false; From 7d8894dc681336248ebd2c6e068f39bcdd2e9477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 6 May 2025 13:46:34 +0200 Subject: [PATCH 2/4] Disable cache in tests --- src/Components/WebAssembly/Directory.Build.props | 3 +++ src/Components/test/testassets/Directory.Build.props | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/Components/WebAssembly/Directory.Build.props b/src/Components/WebAssembly/Directory.Build.props index 836334255bca..b64f9033fc9a 100644 --- a/src/Components/WebAssembly/Directory.Build.props +++ b/src/Components/WebAssembly/Directory.Build.props @@ -7,4 +7,7 @@ false + + false + diff --git a/src/Components/test/testassets/Directory.Build.props b/src/Components/test/testassets/Directory.Build.props index a89953ccb515..f9fe6e921bf4 100644 --- a/src/Components/test/testassets/Directory.Build.props +++ b/src/Components/test/testassets/Directory.Build.props @@ -22,4 +22,7 @@ false + + false + From ed39131e00739d032584a9f705a98fb5cd713e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 6 May 2025 15:00:06 +0200 Subject: [PATCH 3/4] Update BootResourceCachingTest tests --- .../BootResourceRequestLog.cs | 9 +- .../HostedInAspNet.Server/Startup.cs | 10 +- .../E2ETest/Tests/BootResourceCachingTest.cs | 105 +----------------- 3 files changed, 13 insertions(+), 111 deletions(-) diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs index dcd1f2c94325..0764e4b44d8b 100644 --- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs +++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/BootResourceRequestLog.cs @@ -9,11 +9,14 @@ public class BootResourceRequestLog { private readonly ConcurrentBag _requestPaths = new ConcurrentBag(); - public IReadOnlyCollection RequestPaths => _requestPaths; + public IReadOnlyCollection RequestPathsWithNewContent => _requestPaths; - public void AddRequest(HttpRequest request) + public void AddRequest(HttpRequest request, HttpResponse response) { - _requestPaths.Add(request.Path); + if (response.StatusCode != StatusCodes.Status304NotModified) + { + _requestPaths.Add(request.Path); + } } public void Clear() diff --git a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs index 7225c954e2b8..edd6882eb464 100644 --- a/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs +++ b/src/Components/WebAssembly/testassets/HostedInAspNet.Server/Startup.cs @@ -24,17 +24,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, BootReso { var mapAlternativePathApp = Configuration.GetValue("UseAlternativeBasePath"); var mapAllApps = Configuration.GetValue("MapAllApps"); - app.Use((context, next) => + app.Use(async (context, next) => { + await next(context); + // This is used by E2E tests to verify that the correct resources were fetched, // and that it was possible to override the loading mechanism if (context.Request.Query.ContainsKey("customizedbootresource") - || context.Request.Headers.ContainsKey("customizedbootresource") - || context.Request.Path.Value.EndsWith("/blazor.boot.json", StringComparison.Ordinal)) + || context.Request.Headers.ContainsKey("customizedbootresource")) { - bootResourceRequestLog.AddRequest(context.Request); + bootResourceRequestLog.AddRequest(context.Request, context.Response); } - return next(context); }); if (env.IsDevelopment()) diff --git a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs index b15e36dff42f..01c80f3f84da 100644 --- a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs +++ b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs @@ -56,114 +56,13 @@ public void CachesResourcesAfterFirstLoad() Navigate("/"); WaitUntilLoaded(); var subsequentResourcesRequested = GetAndClearRequestedPaths(); - Assert.DoesNotContain(subsequentResourcesRequested, path => - path.Contains("/dotnet.native.", StringComparison.Ordinal) && - path.EndsWith(".wasm", StringComparison.Ordinal)); - Assert.NotEmpty(subsequentResourcesRequested.Where(path => path.EndsWith(".js", StringComparison.Ordinal))); - Assert.DoesNotContain(subsequentResourcesRequested, path => - !path.Contains("/dotnet.native.", StringComparison.Ordinal) && - path.EndsWith(".wasm", StringComparison.Ordinal)); - } - - [Fact] - public async Task IncrementallyUpdatesCache() - { - // Perform a first load to populate the cache - Navigate("/"); - WaitUntilLoaded(); - var cacheEntryUrls1 = GetCacheEntryUrls(); - var cacheEntryForComponentsDll = cacheEntryUrls1.Single(IsFingerprintedComponentsEntry); - var cacheEntryForDotNetWasm = cacheEntryUrls1.Single(IsFingerprintedDotNetWasmEntry); - var cacheEntryForDotNetWasmWithChangedHash = cacheEntryForDotNetWasm.Replace(".sha256-", ".sha256-different"); - - // Remove some items we do need, and add an item we don't need - RemoveCacheEntry(cacheEntryForComponentsDll); - RemoveCacheEntry(cacheEntryForDotNetWasm); - AddCacheEntry(cacheEntryForDotNetWasmWithChangedHash, "ignored content"); - var cacheEntryUrls2 = GetCacheEntryUrls(); - Assert.DoesNotContain(cacheEntryForComponentsDll, cacheEntryUrls2); - Assert.DoesNotContain(cacheEntryForDotNetWasm, cacheEntryUrls2); - Assert.Contains(cacheEntryForDotNetWasmWithChangedHash, cacheEntryUrls2); - - // On the next load, we'll fetch only the items we need (not things already cached) - GetAndClearRequestedPaths(); - Navigate("about:blank"); - Browser.Equal(string.Empty, () => Browser.Title); - Navigate("/"); - WaitUntilLoaded(); - var subsequentResourcesRequested = GetAndClearRequestedPaths(); - Assert.Collection(subsequentResourcesRequested.Where(url => url.Contains(".wasm")), - requestedDll => Assert.True(IsFingerprintedComponentsEntry(requestedDll)), - requestedDll => Assert.True(IsFingerprintedDotNetWasmEntry(requestedDll))); - - var cacheEntryUrls3 = GetCacheEntryUrls(); - // wait until the cache was cleaned, max 500ms - for (var i = 0; i < 5; i++) - { - if (!cacheEntryUrls3.Contains(cacheEntryForDotNetWasmWithChangedHash)) - { - break; - } - await Task.Delay(100); // wait for cache purge - cacheEntryUrls3 = GetCacheEntryUrls(); - } - Assert.Contains(cacheEntryForComponentsDll, cacheEntryUrls3); - Assert.Contains(cacheEntryForDotNetWasm, cacheEntryUrls3); - Assert.DoesNotContain(cacheEntryForDotNetWasmWithChangedHash, cacheEntryUrls3); - } - - [GeneratedRegex("/Microsoft\\.AspNetCore\\.Components\\.\\w*\\.wasm")] - private static partial Regex GetFingerprintedComponentsEntryRegex { get; } - - [GeneratedRegex("/dotnet\\.native\\.\\w*\\.wasm")] - private static partial Regex GetFingerprintedDotNetWasmEntryRegex { get; } - - private static bool IsFingerprintedComponentsEntry(string url) - => GetFingerprintedComponentsEntryRegex.IsMatch(url); - - private static bool IsFingerprintedDotNetWasmEntry(string url) - => GetFingerprintedDotNetWasmEntryRegex.IsMatch(url); - - private IReadOnlyCollection GetCacheEntryUrls() - { - var js = @" - (async function(cacheName, completedCallback) { - const cache = await caches.open(cacheName); - const keys = await cache.keys(); - const urls = keys.map(r => r.url); - completedCallback(urls); - }).apply(null, arguments)"; - var jsExecutor = (IJavaScriptExecutor)Browser; - var result = (IEnumerable)jsExecutor.ExecuteAsyncScript(js, CacheName); - return result.Cast().ToList(); - } - - private void RemoveCacheEntry(string url) - { - var js = @" - (async function(cacheName, urlToRemove, completedCallback) { - const cache = await caches.open(cacheName); - await cache.delete(urlToRemove); - completedCallback(); - }).apply(null, arguments)"; - ((IJavaScriptExecutor)Browser).ExecuteAsyncScript(js, CacheName, url); - } - - private void AddCacheEntry(string url, string content) - { - var js = @" - (async function(cacheName, urlToAdd, contentToAdd, completedCallback) { - const cache = await caches.open(cacheName); - await cache.put(urlToAdd, new Response(contentToAdd)); - completedCallback(); - }).apply(null, arguments)"; - ((IJavaScriptExecutor)Browser).ExecuteAsyncScript(js, CacheName, url, content); + Assert.Empty(subsequentResourcesRequested); } private IReadOnlyCollection GetAndClearRequestedPaths() { var requestLog = _serverFixture.Host.Services.GetRequiredService(); - var result = requestLog.RequestPaths.ToList(); + var result = requestLog.RequestPathsWithNewContent.ToList(); requestLog.Clear(); return result; } From 456454f78dd6681d5de4dbdc8c3e94df8230ec33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Tue, 6 May 2025 15:02:58 +0200 Subject: [PATCH 4/4] Fix typo --- src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs index 01c80f3f84da..d40c7612866e 100644 --- a/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs +++ b/src/Components/test/E2ETest/Tests/BootResourceCachingTest.cs @@ -19,9 +19,6 @@ namespace Microsoft.AspNetCore.Components.E2ETest.Tests; public partial class BootResourceCachingTest : ServerTestBase { - // The cache name is derived from the application's base href value (in this case, '/') - private const string CacheName = "dotnet-resources-/"; - public BootResourceCachingTest( BrowserFixture browserFixture, AspNetSiteServerFixture serverFixture,