From 8debc4a443226dbfb32e63c633f09a940b226cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Wed, 22 Apr 2026 15:27:07 +0000 Subject: [PATCH 1/7] Enable non-AOT WBT tests on CoreCLR in 4 native test classes Remove class-level [TestCategory("native")] from NativeBuildTests, NativeLibraryTests, PInvokeTableGeneratorTests, and DllImportTests so non-AOT methods pass the CoreCLR xunit filter (-notrait category=native). AOT-only methods get a method-level [TestCategory("native")] to keep them excluded on CoreCLR. NativeLibraryTests: four mixed theories (both aot=false and aot=true inline data) are split into a non-AOT theory and a separate AOT-only theory tagged 'native', because xunit trait filtering is per-method, not per-theory-row. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../wasm/Wasm.Build.Tests/DllImportTests.cs | 1 - .../wasm/Wasm.Build.Tests/NativeBuildTests.cs | 4 +- .../Wasm.Build.Tests/NativeLibraryTests.cs | 42 ++++++++++++++++--- .../PInvokeTableGeneratorTests.cs | 3 +- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs b/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs index 4d84a6d567dc0e..dac78c679157ce 100644 --- a/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/DllImportTests.cs @@ -14,7 +14,6 @@ namespace Wasm.Build.Tests { - [TestCategory("native")] public class DllImportTests : PInvokeTableGeneratorTestsBase { public DllImportTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs index ff33906df14d1a..689377aa7bb97b 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeBuildTests.cs @@ -13,7 +13,6 @@ namespace Wasm.Build.Tests { - [TestCategory("native")] public class NativeBuildTests : WasmTemplateTestsBase { public NativeBuildTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) @@ -41,6 +40,7 @@ public async Task SimpleNativeBuild(Configuration config, bool aot) [Theory] [BuildAndRun(aot: true)] + [TestCategory("native")] public void AOTNotSupportedWithNoTrimming(Configuration config, bool aot) { ProjectInfo info = CreateWasmTemplateProject( @@ -59,6 +59,7 @@ public void AOTNotSupportedWithNoTrimming(Configuration config, bool aot) [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] + [TestCategory("native")] public void IntermediateBitcodeToObjectFilesAreNotLLVMIR(Configuration config, bool aot) { string printFileTypeTarget = @" @@ -91,6 +92,7 @@ public void IntermediateBitcodeToObjectFilesAreNotLLVMIR(Configuration config, b [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] + [TestCategory("native")] public void NativeBuildIsRequired(Configuration config, bool aot) { ProjectInfo info = CreateWasmTemplateProject( diff --git a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs index 9cbe49352c147c..ce9b35aa0b3838 100644 --- a/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/NativeLibraryTests.cs @@ -11,7 +11,6 @@ namespace Wasm.Build.Tests { - [TestCategory("native")] public class NativeLibraryTests : WasmTemplateTestsBase { public NativeLibraryTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) @@ -21,8 +20,16 @@ public NativeLibraryTests(ITestOutputHelper output, SharedBuildPerTestClassFixtu [Theory] [BuildAndRun(aot: false)] + public Task ProjectWithNativeReference(Configuration config, bool aot) => + ProjectWithNativeReferenceCore(config, aot); + + [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] - public async Task ProjectWithNativeReference(Configuration config, bool aot) + [TestCategory("native")] + public Task ProjectWithNativeReference_AOT(Configuration config, bool aot) => + ProjectWithNativeReferenceCore(config, aot); + + private async Task ProjectWithNativeReferenceCore(Configuration config, bool aot) { string objectFilename = "native-lib.o"; string extraItems = $""; @@ -42,9 +49,18 @@ public async Task ProjectWithNativeReference(Configuration config, bool aot) [Theory] [BuildAndRun(aot: false)] + [ActiveIssue("https://github.com/dotnet/runtime/issues/103566")] + public Task ProjectUsingSkiaSharp(Configuration config, bool aot) => + ProjectUsingSkiaSharpCore(config, aot); + + [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] + [TestCategory("native")] [ActiveIssue("https://github.com/dotnet/runtime/issues/103566")] - public async Task ProjectUsingSkiaSharp(Configuration config, bool aot) + public Task ProjectUsingSkiaSharp_AOT(Configuration config, bool aot) => + ProjectUsingSkiaSharpCore(config, aot); + + private async Task ProjectUsingSkiaSharpCore(Configuration config, bool aot) { string prefix = $"AppUsingSkiaSharp"; string extraItems = @$" @@ -62,8 +78,16 @@ public async Task ProjectUsingSkiaSharp(Configuration config, bool aot) [Theory] [BuildAndRun(aot: false)] + public Task ProjectUsingBrowserNativeCrypto(Configuration config, bool aot) => + ProjectUsingBrowserNativeCryptoCore(config, aot); + + [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] - public async Task ProjectUsingBrowserNativeCrypto(Configuration config, bool aot) + [TestCategory("native")] + public Task ProjectUsingBrowserNativeCrypto_AOT(Configuration config, bool aot) => + ProjectUsingBrowserNativeCryptoCore(config, aot); + + private async Task ProjectUsingBrowserNativeCryptoCore(Configuration config, bool aot) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "AppUsingBrowserNativeCrypto"); ReplaceFile(Path.Combine("Common", "Program.cs"), Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "NativeCrypto.cs")); @@ -80,8 +104,16 @@ public async Task ProjectUsingBrowserNativeCrypto(Configuration config, bool aot [Theory] [BuildAndRun(aot: false)] + public Task ProjectWithNativeLibrary(Configuration config, bool aot) => + ProjectWithNativeLibraryCore(config, aot); + + [Theory] [BuildAndRun(config: Configuration.Release, aot: true)] - public async Task ProjectWithNativeLibrary(Configuration config, bool aot) + [TestCategory("native")] + public Task ProjectWithNativeLibrary_AOT(Configuration config, bool aot) => + ProjectWithNativeLibraryCore(config, aot); + + private async Task ProjectWithNativeLibraryCore(Configuration config, bool aot) { string extraItems = "\n"; ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "AppUsingNativeLib-a", extraItems: extraItems); diff --git a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs index f88a5013b92f95..604eadcdd7f53d 100644 --- a/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/PInvokeTableGeneratorTests.cs @@ -14,7 +14,6 @@ namespace Wasm.Build.Tests { - [TestCategory("native")] public class PInvokeTableGeneratorTests : PInvokeTableGeneratorTestsBase { public PInvokeTableGeneratorTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) @@ -351,6 +350,7 @@ private async Task EnsureWasmAbiRulesAreFollowed(Configuration config, bool aot) [Theory] [BuildAndRun(aot: true, config: Configuration.Release)] + [TestCategory("native")] public async Task EnsureWasmAbiRulesAreFollowedInAOT(Configuration config, bool aot) => await EnsureWasmAbiRulesAreFollowed(config, aot); @@ -361,6 +361,7 @@ public async Task EnsureWasmAbiRulesAreFollowedInInterpreter(Configuration confi [Theory] [BuildAndRun(aot: true, config: Configuration.Release)] + [TestCategory("native")] public void EnsureComInteropCompilesInAOT(Configuration config, bool aot) { ProjectInfo info = CopyTestAsset(config, aot, TestAsset.WasmBasicTestApp, "com"); From 65e6237d5cb39688574908dc6dcd506a8242139a Mon Sep 17 00:00:00 2001 From: Copilot <223556219+Copilot@users.noreply.github.com> Date: Fri, 24 Apr 2026 10:30:56 +0200 Subject: [PATCH 2/7] Enable ICU, InvariantGlobalization, and Memory tests on CoreCLR Change [TestCategory("native")] to [TestCategory("native-coreclr")] for tests that use native relink but should also run on CoreCLR: - IcuShardingTests: CustomIcuShard, AutomaticShardSelectionDependingOnEnvLocale - IcuShardingTests2: DefaultAvailableIcuShardsFromRuntimePack - IcuTests: FullIcuFromRuntimePackWithInvariant, FullIcuFromRuntimePackWithCustomIcu - InvariantGlobalizationTests: RelinkingWithoutAOT - MemoryTests: entire class (AllocateLargeHeapThenRepeatedlyInterop) CoreCLR always has native relink support, so these tests can run on both Mono and CoreCLR. The CoreCLR xunit filter excludes category=native but not category=native-coreclr. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs | 4 ++-- src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs | 2 +- src/mono/wasm/Wasm.Build.Tests/IcuTests.cs | 4 ++-- src/mono/wasm/Wasm.Build.Tests/InvariantGlobalizationTests.cs | 2 +- src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs index 2883967abc0105..4975294e26448c 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests.cs @@ -41,13 +41,13 @@ from locale in locales [Theory] [MemberData(nameof(IcuExpectedAndMissingCustomShardTestData), parameters: new object[] { Configuration.Release })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task CustomIcuShard(Configuration config, bool aot, string customIcuPath, string customLocales, bool onlyPredefinedCultures) => await TestIcuShards(config, Template.WasmBrowser, aot, customIcuPath, customLocales, GlobalizationMode.Custom, onlyPredefinedCultures); [Theory] [MemberData(nameof(IcuExpectedAndMissingAutomaticShardTestData), parameters: new object[] { Configuration.Release })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task AutomaticShardSelectionDependingOnEnvLocale(Configuration config, bool aot, string environmentLocale, string testedLocales) => await PublishAndRunIcuTest(config, Template.WasmBrowser, aot, testedLocales, GlobalizationMode.Sharded, locale: environmentLocale); } diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs index 7005b99642b21e..fc7b0316dca708 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuShardingTests2.cs @@ -38,7 +38,7 @@ from locale in locales [Theory] [MemberData(nameof(IcuExpectedAndMissingShardFromRuntimePackTestData), parameters: new object[] { Configuration.Release })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task DefaultAvailableIcuShardsFromRuntimePack(Configuration config, bool aot, string shardName, string testedLocales) => await TestIcuShards(config, Template.WasmBrowser, aot, shardName, testedLocales, GlobalizationMode.Custom); } diff --git a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs index f57e229bc0200d..b67e7c1a9bfba1 100644 --- a/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/IcuTests.cs @@ -53,7 +53,7 @@ public static IEnumerable IncorrectIcuTestData(Configuration config) [Theory] [MemberData(nameof(FullIcuWithInvariantTestData), parameters: new object[] { Configuration.Release })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task FullIcuFromRuntimePackWithInvariant(Configuration config=Configuration.Release, bool aot=false, bool invariant=true, bool fullIcu=true, string testedLocales="Array.Empty()") => await PublishAndRunIcuTest( config, @@ -67,7 +67,7 @@ await PublishAndRunIcuTest( [Theory] [MemberData(nameof(FullIcuWithICustomIcuTestData), parameters: new object[] { Configuration.Release })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task FullIcuFromRuntimePackWithCustomIcu(Configuration config, bool aot, bool fullIcu) { string customIcuProperty = "BlazorIcuDataFileName"; diff --git a/src/mono/wasm/Wasm.Build.Tests/InvariantGlobalizationTests.cs b/src/mono/wasm/Wasm.Build.Tests/InvariantGlobalizationTests.cs index 9a7950b7a5ec4b..6d35c3265ac4d0 100644 --- a/src/mono/wasm/Wasm.Build.Tests/InvariantGlobalizationTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/InvariantGlobalizationTests.cs @@ -39,7 +39,7 @@ public async Task AOT_InvariantGlobalization(Configuration config, bool aot, boo // TODO: What else should we use to verify a relinked build? [Theory] [MemberData(nameof(InvariantGlobalizationTestData), parameters: new object[] { /*aot*/ false })] - [TestCategory("native")] + [TestCategory("native-coreclr")] public async Task RelinkingWithoutAOT(Configuration config, bool aot, bool? invariantGlobalization) => await TestInvariantGlobalization(config, aot, invariantGlobalization, isNativeBuild: true); diff --git a/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs b/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs index d4c4a32c3b6412..e796b8791476e6 100644 --- a/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs +++ b/src/mono/wasm/Wasm.Build.Tests/MemoryTests.cs @@ -13,7 +13,7 @@ namespace Wasm.Build.Tests; -[TestCategory("native")] +[TestCategory("native-coreclr")] public class MemoryTests : WasmTemplateTestsBase { public MemoryTests(ITestOutputHelper output, SharedBuildPerTestClassFixture buildContext) From 1fa495029cd707af2405efa3ec6e2aed510552d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 24 Apr 2026 10:02:59 +0000 Subject: [PATCH 3/7] Add newly enabled WBT classes to CoreCLR Helix jobs list Without these entries in BuildWasmAppsJobsListCoreCLR.txt, the test classes whose class-level [TestCategory("native")] was removed (or retagged to native-coreclr) in this PR would still not be scheduled as Helix work items for the CoreCLR BuildWasmApps scenario. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt b/eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt index 4f567f5cba1082..f6cbcd4dd63241 100644 --- a/eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt +++ b/eng/testing/scenarios/BuildWasmAppsJobsListCoreCLR.txt @@ -12,3 +12,12 @@ Wasm.Build.Tests.WasmRunOutOfAppBundleTests Wasm.Build.Tests.WasmTemplateTests Wasm.Build.Tests.MaxParallelDownloadsTests Wasm.Build.Tests.LibraryInitializerTests +Wasm.Build.Tests.NativeBuildTests +Wasm.Build.Tests.DllImportTests +Wasm.Build.Tests.PInvokeTableGeneratorTests +Wasm.Build.Tests.NativeLibraryTests +Wasm.Build.Tests.IcuShardingTests +Wasm.Build.Tests.IcuShardingTests2 +Wasm.Build.Tests.IcuTests +Wasm.Build.Tests.InvariantGlobalizationTests +Wasm.Build.Tests.MemoryTests From 123b86384ef72b97092d398f3f14a2bec4acc688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Fi=C5=A1era?= Date: Fri, 24 Apr 2026 12:41:44 +0000 Subject: [PATCH 4/7] Fix WBT template install on read-only Helix correlation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EnsureWasmTemplatesInstalled placed .dotnet-cli-home next to the template nupkg (which on Linux Helix agents is under the read-only correlation payload), causing 'Read-only file system' / 'Access denied' errors for every test class that calls CreateWasmTemplateProject. Always use BuildEnvironment.TmpPath — the harness's writable scratch dir — instead. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs index c5d56480561582..107be573032a9a 100644 --- a/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs +++ b/src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs @@ -216,10 +216,10 @@ private static void EnsureWasmTemplatesInstalled() UseShellExecute = false }; // Isolate the template cache so the install doesn't touch the default user profile - // and can't collide across Helix jobs/agents (or fail if the profile is not writable). - string dotnetCliHome = s_buildEnv.EnvVars.TryGetValue("NUGET_PACKAGES", out string? nugetPackagesPath) && !string.IsNullOrWhiteSpace(nugetPackagesPath) - ? Path.Combine(Path.GetDirectoryName(nugetPackagesPath)!, ".dotnet-cli-home") - : Path.Combine(Path.GetDirectoryName(templateNupkg)!, ".dotnet-cli-home"); + // and can't collide across Helix jobs/agents. Always place it in TmpPath — the + // test harness's writable scratch dir — because the nupkg can live under the + // Helix correlation payload, which is read-only on Linux agents. + string dotnetCliHome = Path.Combine(BuildEnvironment.TmpPath, ".dotnet-cli-home"); Directory.CreateDirectory(dotnetCliHome); // Use the same isolated environment as the rest of the test suite From 52509275fd4e1aa577a5006da1008f1976e5f537 Mon Sep 17 00:00:00 2001 From: maraf Date: Mon, 27 Apr 2026 08:31:49 +0000 Subject: [PATCH 5/7] Fix WBT template install DOTNET_CLI_HOME mismatch on Helix EnsureWasmTemplatesInstalled set DOTNET_CLI_HOME to TmpPath/.dotnet-cli-home when running 'dotnet new install'. The subsequent 'dotnet new