From e0d72389527c8c604d7d0d7b9bd69d6ed11bdad9 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Mon, 13 Jul 2026 13:23:14 +0200 Subject: [PATCH 1/2] [wasm] Fix ReferenceNewAssembly rebuild test: driver-gen.c not regenerated The test replaced Program.cs to use System.Security.Cryptography (SHA256), expecting a new assembly to be added to the AOT set so driver-gen.c (the AOT modules table) would be regenerated. However WasmBasicTestApp already pulls System.Security.Cryptography into its closure via HttpTest.cs (HttpClient -> System.Net.Http -> crypto), so the AOT assembly set was identical before and after the change. driver-gen.c is written with CopyIfDifferent, so its timestamp was unchanged and the 'Expected changed file: driver-gen.c' assertion failed (deterministically, Release/aot=True). Additionally reference System.Text.RegularExpressions, which is not otherwise part of the app closure, so the rebuild genuinely adds a new AOT module and driver-gen.c is regenerated. Fixes #130540. --- .../testassets/EntryPoints/NativeRebuildNewAssembly.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/mono/wasm/testassets/EntryPoints/NativeRebuildNewAssembly.cs b/src/mono/wasm/testassets/EntryPoints/NativeRebuildNewAssembly.cs index bff7ffb3827a40..931f177dc8a10e 100644 --- a/src/mono/wasm/testassets/EntryPoints/NativeRebuildNewAssembly.cs +++ b/src/mono/wasm/testassets/EntryPoints/NativeRebuildNewAssembly.cs @@ -1,6 +1,7 @@ using System; using System.Security.Cryptography; using System.Text; +using System.Text.RegularExpressions; public class Test { public static int Main() @@ -12,6 +13,13 @@ public static int Main() byte[] hashBytes = sha256.ComputeHash(inputBytes); Console.WriteLine($"Hash of {input}: {Convert.ToBase64String(hashBytes)}"); } + + // Also reference System.Text.RegularExpressions, which is not otherwise part of + // the test app's closure, so that rebuilding pulls in a *new* assembly. This + // ensures native artifacts that depend on the set of assemblies (e.g. the AOT + // modules table driver-gen.c) are regenerated on rebuild. + bool isMatch = Regex.IsMatch(input, "[A-Za-z]+"); + Console.WriteLine($"Input '{input}' matches: {isMatch}"); return 42; } } From bb28540aa62872e90d58dea78574725bc0d89eb7 Mon Sep 17 00:00:00 2001 From: pavelsavara Date: Tue, 14 Jul 2026 11:30:38 +0200 Subject: [PATCH 2/2] [wasm] WBT: pick newest fingerprinted native on republish to avoid stale-file comparison ReferenceNewAssemblyRebuildTest publishes twice into the same wwwroot. The rebuild relinks dotnet.native.wasm to a larger, differently-fingerprinted file, but the first publish's fingerprinted copy is not removed. FindAndAssertDotnetFiles globbed dotnet.* and kept the alphabetically-last match, which could be the stale file, causing an order-dependent 'File sizes don't match' failure. Keep the newest matching file (the current rebuild output) instead. --- .../wasm/Wasm.Build.Tests/ProjectProviderBase.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs index 301661f69af9f3..ccd4b435dc5253 100644 --- a/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/ProjectProviderBase.cs @@ -129,9 +129,19 @@ public IReadOnlyDictionary FindAndAssertDotnetFiles( if (!match.Success) return true; - actual[expectedFilename] = new(ExpectedFilename: expectedFilename, - Hash: match.Groups[1].Value, - ActualPath: actualFile); + // Multiple fingerprinted variants of the same logical file can coexist when + // republishing into an existing output directory: the previous publish's + // fingerprinted copy is not removed, and a rebuild that changes the file's + // content produces a new fingerprint alongside the stale one. Keep the newest + // file so the assertion compares against the current (re)build output instead + // of picking a stale artifact by filename ordering. + if (!actual.TryGetValue(expectedFilename, out DotNetFileName? existingMatch) || + File.GetLastWriteTimeUtc(actualFile) >= File.GetLastWriteTimeUtc(existingMatch.ActualPath)) + { + actual[expectedFilename] = new(ExpectedFilename: expectedFilename, + Hash: match.Groups[1].Value, + ActualPath: actualFile); + } } else {