[browser] More Wasm.Build.Tests on CoreCLR#127281
[browser] More Wasm.Build.Tests on CoreCLR#127281maraf wants to merge 21 commits intodotnet:mainfrom
Conversation
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
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>
07aa682 to
8debc4a
Compare
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>
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>
| [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<Locale>()") => |
There was a problem hiding this comment.
Changing these theories to TestCategory("native-coreclr") makes them eligible to run under the CoreCLR lane filter (which only excludes category=native). However, the test data includes aot=true cases (boolOptions), and CoreCLR builds set <UseMonoRuntime>false</UseMonoRuntime>; AOT compilation is likely unsupported and will attempt to run anyway. Consider splitting into non-AOT methods (tagged native-coreclr) and AOT methods (keep category=native so they remain excluded on CoreCLR), or adjust the MemberData to exclude aot=true when BuildTestBase.IsCoreClrRuntime.
| [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) => |
There was a problem hiding this comment.
These tests use boolOptions for the aot parameter (so they generate AOT and non-AOT variants). Retagging them to native-coreclr will cause the AOT variants to run on the CoreCLR lane (since only category=native is excluded), which is likely unsupported for CoreCLR (UseMonoRuntime=false). Split/tag AOT variants as category=native (excluded on CoreCLR) or filter aot=true out for CoreCLR runs.
| [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) => |
There was a problem hiding this comment.
This theory generates both aot=false and aot=true cases via boolOptions. After changing the category to native-coreclr, the AOT variants will no longer be excluded by the CoreCLR trait filter (-notrait category=native) and may run on CoreCLR where AOT is likely unsupported. Consider splitting/tagging AOT variants as category=native (excluded) or changing the data source to omit aot=true on CoreCLR.
| [TestCategory("native-coreclr")] | ||
| public class MemoryTests : WasmTemplateTestsBase |
There was a problem hiding this comment.
With the class retagged to native-coreclr, this test will start running in the CoreCLR lane. The build assertion currently uses ExpectSuccess: BuildTestBase.IsUsingWorkloads, but CoreCLR WBT runs with TestUsingWorkloads=false while native relink is now supported (emsdk is provisioned separately). That combination likely makes the test fail (it will expect the native build to fail even if it succeeds). Consider basing ExpectSuccess/execution on whether native builds are actually available (e.g., IsUsingWorkloads || IsCoreClrRuntime), or keep the test excluded until its expectations are updated.
| Wasm.Build.Tests.IcuShardingTests | ||
| Wasm.Build.Tests.IcuShardingTests2 | ||
| Wasm.Build.Tests.IcuTests | ||
| Wasm.Build.Tests.InvariantGlobalizationTests | ||
| Wasm.Build.Tests.MemoryTests |
There was a problem hiding this comment.
The PR description says additional TestCategory("native") classes like IcuTests are "not in scope" and left for follow-up, but this change adds Icu*, InvariantGlobalizationTests, and MemoryTests to the CoreCLR job list. Either update the PR description to reflect the expanded scope or remove these additions to match the stated intent.
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>
EnsureWasmTemplatesInstalled set DOTNET_CLI_HOME to TmpPath/.dotnet-cli-home when running 'dotnet new install'. The subsequent 'dotnet new <template>' call goes through DotNetCommand(useDefaultArgs: false), which does not apply BuildEnvironment.EnvVars to the child process, so it inherited the Helix-set DOTNET_CLI_HOME (e.g. /root/helix/work/workitem/e/.dotnet). Two different DOTNET_CLI_HOME values mean two different template caches: the install lands in one, the lookup misses in the other, producing 'No templates or subcommands found matching: wasmbrowser' (exit 103) on every test class that calls CreateWasmTemplateProject. Prefer the inherited DOTNET_CLI_HOME so install and lookup share a cache; fall back to TmpPath only when not set (preserves the read-only-FS fix for environments without an inherited value). Reproduced locally with DOTNET_CLI_HOME=/tmp/helix-cli-home; templates were installed under wbt artifacts/.dotnet-cli-home but 'dotnet new' read from /tmp/helix-cli-home. After the fix, both paths share /tmp/helix-cli-home and 'dotnet new wasmbrowser' succeeds. Also adds [diag] Console.WriteLine entries logging both the install-time and invocation-time DOTNET_CLI_HOME so Helix work-item console logs make similar future regressions trivial to diagnose. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs:104
EnsureWasmTemplatesInstalledsetsDOTNET_CLI_HOMEonly for thedotnet new installprocess. The subsequentdotnet new <template>invocation (viaDotNetCommand(..., useDefaultArgs:false)) does not setDOTNET_CLI_HOME, so it may look in a different template cache whenDOTNET_CLI_HOMEis not already set in the test process environment (e.g., local runs). To make this robust, propagate the chosendotnetCliHometo thedotnet new <template>command (or set it on the current process viaEnvironment.SetEnvironmentVariablebefore invokingdotnet new).
// [diag] Log DOTNET_CLI_HOME inherited by the `dotnet new <template>` invocation.
// The template engine reads installed templates from this location; if it differs
// from the DOTNET_CLI_HOME used by EnsureWasmTemplatesInstalled, the template
// won't be found.
string inheritedCliHome = Environment.GetEnvironmentVariable("DOTNET_CLI_HOME") ?? "<unset>";
string envVarsCliHome = s_buildEnv.EnvVars.TryGetValue("DOTNET_CLI_HOME", out string? evCliHome) ? evCliHome : "<unset-in-EnvVars>";
Console.WriteLine($"[diag] DOTNET_CLI_HOME inherited by `dotnet new {template.ToString().ToLower()}`: '{inheritedCliHome}' (buildEnv.EnvVars: '{envVarsCliHome}')");
using DotNetCommand cmd = new DotNetCommand(s_buildEnv, _testOutput, useDefaultArgs: false);
CommandResult result = cmd.WithWorkingDirectory(_projectDir)
.WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir)
.ExecuteWithCapturedOutput($"new {template.ToString().ToLower()} {extraArgs}")
.EnsureSuccessful();
- Inline callhelpers.hpp / minipal/entrypoints.h declarations into the pre-included coreclr_compat.h and stop emitting #include lines for those headers from the CoreCLR generators, so pinvoke-table.cpp and wasm_m2n_invoke.g.cpp compile on Helix where the in-repo header paths do not exist. - Make BuildEnvironment.GetRuntimePackDir flavor-aware: on CoreCLR the runtime pack is Microsoft.NETCore.App.Runtime.<rid> (no .Mono. segment). - Mark DllImportTests.NativeLibraryWithVariadicFunctions as Mono-only; CoreCLR's PInvoke generator does not emit the expected varargs warning. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
….targets
The previous attempt to generate coreclr_compat.h from a _CompatHeaderLines
ItemGroup hit an MSBuild item-spec dedup/parsing issue: items whose Include
value contained both `{...}` braces and embedded `%3B` semicolons were
silently dropped from the output (verified with a minimal repro). That left
the generated header with missing `StringToWasmSigThunk` and
`ReverseThunkMapEntry` struct declarations, so pinvoke-table.cpp /
wasm_m2n_invoke.g.cpp failed to compile on Helix.
Replace the inline ItemGroup generation with a static coreclr_compat.h next
to BrowserWasmApp.CoreCLR.targets and `-include` it via
$(MSBuildThisFileDirectory). The file ships into the Helix correlation
payload via the existing HelixCorrelationPayload Include="$(BrowserBuildTargetsDir)"
mapping (sendtohelix-browser.targets), so it lands at
correlation/build/wasm/coreclr_compat.h alongside the targets file.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs:104
- EnsureWasmTemplatesInstalled may install templates into a fallback DOTNET_CLI_HOME under BuildEnvironment.TmpPath when the process doesn't already have DOTNET_CLI_HOME set, but the subsequent
dotnet new <template>call uses DotNetCommand(useDefaultArgs:false) and does not set DOTNET_CLI_HOME. In that casedotnet newwill look in the default CLI home and won't see the installed templates. Consider explicitly setting DOTNET_CLI_HOME on thedotnet newinvocation (or setting it for the current process) to guarantee both steps share the same template cache in local runs.
EnsureWasmTemplatesInstalled();
// [diag] Log DOTNET_CLI_HOME inherited by the `dotnet new <template>` invocation.
// The template engine reads installed templates from this location; if it differs
// from the DOTNET_CLI_HOME used by EnsureWasmTemplatesInstalled, the template
// won't be found.
string inheritedCliHome = Environment.GetEnvironmentVariable("DOTNET_CLI_HOME") ?? "<unset>";
string envVarsCliHome = s_buildEnv.EnvVars.TryGetValue("DOTNET_CLI_HOME", out string? evCliHome) ? evCliHome : "<unset-in-EnvVars>";
Console.WriteLine($"[diag] DOTNET_CLI_HOME inherited by `dotnet new {template.ToString().ToLower()}`: '{inheritedCliHome}' (buildEnv.EnvVars: '{envVarsCliHome}')");
using DotNetCommand cmd = new DotNetCommand(s_buildEnv, _testOutput, useDefaultArgs: false);
CommandResult result = cmd.WithWorkingDirectory(_projectDir)
.WithEnvironmentVariable("NUGET_PACKAGES", _nugetPackagesDir)
.ExecuteWithCapturedOutput($"new {template.ToString().ToLower()} {extraArgs}")
.EnsureSuccessful();
| // Auto-included CoreCLR compat header for app native build. | ||
| // | ||
| // This header is pre-included via -include when compiling pinvoke-table.cpp |
There was a problem hiding this comment.
New header file is missing the standard .NET Foundation MIT license header comment used throughout the repo. Please add the usual "Licensed to the .NET Foundation under one or more agreements..." block at the top for consistency/compliance.
| // The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports) | ||
| // which the ICU test program does not use. Replace it with a minimal version tailored | ||
| // for ICU tests, otherwise the JS interop assembly would be linked away by the trimmer. |
There was a problem hiding this comment.
The new comment says the template main.js would cause the JS interop assembly to be linked away by the trimmer, but the reason to replace main.js seems to be the opposite: avoid calling JS interop APIs (setModuleImports/getAssemblyExports) so the app doesn't depend on JS interop being preserved. Please clarify the comment to reflect the actual failure mode/intent (e.g., default main.js calls these APIs but the app doesn't reference the managed JS interop pieces, so trimming can remove them and the default main.js would then fail at runtime).
| // The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports) | |
| // which the ICU test program does not use. Replace it with a minimal version tailored | |
| // for ICU tests, otherwise the JS interop assembly would be linked away by the trimmer. | |
| // The template main.js calls JS interop APIs (setModuleImports, getAssemblyExports), | |
| // but the ICU test program does not reference the managed JS interop pieces. Trimming | |
| // can therefore remove them, and the default main.js would then fail at runtime, so | |
| // replace it with a minimal version tailored for ICU tests that avoids those APIs. |
| [TestCategory("native-coreclr")] | ||
| public class MemoryTests : WasmTemplateTestsBase | ||
| { |
There was a problem hiding this comment.
With the class category changed to "native-coreclr", this test class will now run on the CoreCLR WBT lane (which sets SDK_HAS_WORKLOAD_INSTALLED=false). In that lane, AllocateLargeHeapThenRepeatedlyInterop calls BuildProject(... ExpectSuccess: BuildTestBase.IsUsingWorkloads) which becomes false, so the test effectively expects the build to fail and then doesn't run/validate anything. If the intent is to start exercising this scenario on CoreCLR, consider splitting the workload/no-workload variants (or tagging the workload-only [Fact] with TestCategory("workload")) and making the CoreCLR-enabled path assert a successful native rebuild instead of treating failure as success.
ManagedToNativeGenerator output (wasm_m2n_invoke.g.cpp) uses NOINLINE, which is defined in src/native/minipal/utils.h. On Helix, the WBT correlation payload only had coreclr_compat.h — no NOINLINE definition — so per-app native re-link failed for newly-enabled CoreCLR WBT classes (InvariantGlobalizationTests.RelinkingWithoutAOT, DllImportTests.*). Stage src/native/minipal/utils.h into the WBT correlation payload at build/minipal and force-include it from BrowserWasmApp.CoreCLR.targets alongside coreclr_compat.h. The include directory is provided to the targets via MINIPAL_INCLUDE_DIR (HelixPreCommand on Helix, RunScriptCommands locally), with an in-repo fallback for full repo builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
IcuShardingTests2.DefaultAvailableIcuShardsFromRuntimePack publishes from the per-test NuGet feed (NUGET_PACKAGES override), but ProjectProviderBase.AssertIcuAssets compared the published shard against BuildEnvironment.GetRuntimeNativeDir(...), which resolves to the SDK-installed dotnet/packs/ copy. On CoreCLR no-workload Helix runs the two diverge and the asserts fail looking for icudt_EFIGS/CJK/no_CJK.dat in dotnet-none/packs while the publish-time pack used a different copy under wbt artifacts/nuget/.../microsoft.netcore.app.runtime.browser-wasm. Parse 'MicrosoftNetCoreAppRuntimePackDir' from MSBuild output (the existing regex used by AssertRuntimePackPath) and thread it through AssertBundle / AssertBundleOptions. AssertIcuAssets prefers that path when present, so ICU shard comparisons read from the same pack the publish output came from. For workload runs the resolved path equals GetRuntimeNativeDir, so behavior is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CoreCLR WASM relink path in BrowserWasmApp.CoreCLR.targets references
'$(MicrosoftNetCoreAppRuntimePackRidNativeDir)libSystem.Native.Browser.extpost.js'
as the emcc --extern-post-js input, and corehost.proj copies the file
into the local runtime pack output directory. However, the file is not
listed in the platform manifest in
src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props, so
it gets dropped when the Microsoft.NETCore.App.Runtime.browser-wasm
NuGet package is created. CI legs that consume the packed runtime pack
(e.g. Wasm.Build.Tests on Helix using the per-test NuGet feed) then fail
the link with:
emcc : error : '--extern-post-js': file not found:
.../microsoft.netcore.app.runtime.browser-wasm/11.0.0-ci/runtimes/
browser-wasm/native/libSystem.Native.Browser.extpost.js
Add the file to the manifest alongside the other libSystem.Native.Browser.*
entries so it ships with the runtime pack.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous commit added the file to PlatformManifestFileEntry in
Microsoft.NETCore.App/Directory.Build.props, but that only registers
the file in the platform manifest — it does not cause the file to be
included in the runtime-pack nupkg. The nupkg sources its content from
$(LibrariesSharedFrameworkDir) (artifacts/bin/native/<rid-tfm>/sharedFramework/)
via the *.js glob. Because libSystem.Native.Browser.extpost.js is a
hand-written passthrough source (not a rollup output), nothing was
installing it into that directory.
Add an explicit cmake install for the file in
src/native/libs/Common/JavaScript/CMakeLists.txt so it lands in
sharedFramework and is picked up by:
- the runtime-pack nuspec (-> ships in
Microsoft.NETCore.App.Runtime.browser-wasm.nupkg)
- corehost.proj's CopyWasmNativeFiles via its existing
$(LibrariesSharedFrameworkDir)*.js glob (-> populates the in-tree
runtime pack layout)
Drop the now-redundant explicit include in
src/native/corehost/corehost.proj that pointed at the source file
directly; it is no longer needed once the *.js glob picks it up.
Verified: rebuilt libs.native and the runtime-pack sfxproj; the
generated nupkg now contains
runtimes/browser-wasm/native/libSystem.Native.Browser.extpost.js,
which previously was missing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| // Auto-included CoreCLR compat header for app native build. | ||
| // | ||
| // This header is pre-included via -include when compiling pinvoke-table.cpp | ||
| // and wasm_m2n_invoke.g.cpp produced by ManagedToNativeGenerator, so those | ||
| // files can be compiled outside the full CoreCLR build context (e.g. in |
| private string GetRuntimePackName(RuntimeVariant runtimeType) | ||
| { | ||
| // CoreCLR ships browser-wasm via Microsoft.NETCore.App.Runtime.{rid} (no flavor segment). | ||
| // Mono uses Microsoft.NETCore.App.Runtime.Mono.{rid}, with a separate .multithread. variant. | ||
| if (IsCoreClrRuntime) | ||
| return $"Microsoft.NETCore.App.Runtime.{DefaultRuntimeIdentifier}"; | ||
|
|
||
| return runtimeType is RuntimeVariant.SingleThreaded | ||
| ? $"Microsoft.NETCore.App.Runtime.Mono.{DefaultRuntimeIdentifier}" | ||
| : $"Microsoft.NETCore.App.Runtime.Mono.multithread.{DefaultRuntimeIdentifier}"; |
WBT requires all .a archives (libBrowserHost.a, libSystem.Native.Browser.a, libicu*.a, etc.) in the runtime pack to relink with emcc per-app. - Set IncludeStaticLibrariesInPack=true for browser/wasi CoreCLR sfxproj so static libs from LibrariesRuntimeFiles are not filtered out. - Add libBrowserHost.a to the platform manifest. - Exclude duplicate libminipal.a from LibrariesSharedFrameworkDir; the CoreCLR-side libminipal.a is the one referenced by browserhost. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…veLibrary present The Mono path's _SetWasmBuildNativeDefaults auto-flips WasmBuildNative=true when a project has @(NativeFileReference) items, so a project with native P/Invoke targets gets relinked into dotnet.native.wasm. The CoreCLR path had no equivalent, so apps with a NativeLibrary/NativeFileReference would build successfully but fail at runtime with 'DllNotFoundException: dynamic linking not enabled'. Add _CoreCLRSetWasmBuildNativeDefaults that flips WasmBuildNative=true when either NativeFileReference or NativeLibrary items are present. NativeLibrary is later converted to NativeFileReference in _CoreCLRPrepareForNativeBuild, so we count both at the entry-point level. Run the defaults via DependsOnTargets (rather than BeforeTargets) so the mutated WasmBuildNative is visible when _CoreCLRWasmBuildAppCore's Condition is evaluated. The outer entry-point WasmBuildNative check is removed because the inner _CoreCLRWasmBuildAppCore already gates on it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 30 out of 30 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/mono/wasm/Wasm.Build.Tests/Templates/WasmTemplateTestsBase.cs:245
- EnsureWasmTemplatesInstalled picks a fallback DOTNET_CLI_HOME when the process doesn’t already have one, but the subsequent
dotnet new <template>invocation uses DotNetCommand(useDefaultArgs:false) and therefore inherits DOTNET_CLI_HOME from the test process. If it’s unset, templates may be installed into the fallback directory butdotnet newwill still look in the default CLI home and fail to find the template. Consider setting DOTNET_CLI_HOME for the current process (or explicitly for thedotnet newcommand) when you choose the fallback path, so install and usage always share the same template cache.
// Use the inherited DOTNET_CLI_HOME if set (Helix workitems set this to a
// writable workitem path); otherwise fall back to TmpPath. Aligning with
// the inherited value ensures `dotnet new install` and the subsequent
// `dotnet new <template>` invocation share the same template cache —
// those `dotnet new <template>` calls (via DotNetCommand with
// useDefaultArgs:false) inherit DOTNET_CLI_HOME from the test process.
string? inheritedCliHome = Environment.GetEnvironmentVariable("DOTNET_CLI_HOME");
string dotnetCliHome = !string.IsNullOrWhiteSpace(inheritedCliHome)
? inheritedCliHome
: Path.Combine(BuildEnvironment.TmpPath, ".dotnet-cli-home");
Directory.CreateDirectory(dotnetCliHome);
Console.WriteLine($"[diag] DOTNET_CLI_HOME used by EnsureWasmTemplatesInstalled: '{dotnetCliHome}' (process inherited: '{inheritedCliHome ?? "<unset>"}')");
// Use the same isolated environment as the rest of the test suite
// (DOTNET_ROOT/DOTNET_INSTALL_DIR/PATH/NUGET_PACKAGES overrides), so
// `dotnet new install` picks up the harness's SDK and NuGet config.
foreach (var kvp in s_buildEnv.EnvVars)
psi.Environment[kvp.Key] = kvp.Value;
psi.Environment["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = "1";
psi.Environment["DOTNET_CLI_HOME"] = dotnetCliHome;
libSystem.IO.Compression.Native.a, libz.a, and libminipal.a are installed into both $(CoreCLRSharedFrameworkDir) (consumed by corehost when linking dotnet.native.js, and packed via the CoreCLRSharedFrameworkDir RuntimeFiles glob in liveBuilds.targets) and $(LibrariesSharedFrameworkDir) (packed via the browser+CoreCLR LibrariesRuntimeFiles ItemGroup). With IncludeStaticLibrariesInPack=true, both flows produce runtimes/browser-wasm/native/<file>.a, causing NuGet pack to emit NU5118 (warnings-as-errors). Extend the existing Exclude= for libminipal.a to also drop the LibrariesSharedFrameworkDir copies of libSystem.IO.Compression.Native.a and libz.a. corehost continues to consume the CoreCLRSharedFrameworkDir copy at link time, and the runtime pack ends up with exactly one copy of each archive. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both DllImportWithFunctionPointersCompilesWithoutWarning and DllImportWithFunctionPointers_ForVariadicFunction_CompilesWithWarning use the WasmBasicTestApp main.js, which unconditionally calls getAssemblyExports on the main assembly. With CoreCLR-Wasm the trimmer drops System.Runtime.InteropServices.JavaScript because the test program does not use JS interop, so JS startup fails with Arg_TargetInvocationException out of JSHostImplementation.BindAssemblyExports. Mirror the IcuTestsBase fix and overwrite the template main.js with the minimal icu_main.js (no JS interop calls, just runMainAndExit) inside PrepareProjectForVariadicFunction. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Generalize the icu_main.js fix into a shared ReplaceMainJsWithMinimalRunMain helper on WasmTemplateTestsBase, and apply it to additional CoreCLR-Wasm NoWorkload tests whose managed program does not use JS interop. Without it, the WasmBasicTestApp / wasmbrowser template main.js calls getAssemblyExports, which fails at startup with Arg_TargetInvocationException out of JSHostImplementation.BindAssemblyExports because the trimmer drops System.Runtime.InteropServices.JavaScript. Tests updated: - InvariantGlobalizationTests.RelinkingWithoutAOT (and AOT path) - NativeBuildTests.SimpleNativeBuild - NativeLibraryTests.ProjectWithNativeReference / ProjectWithNativeLibrary - PInvokeTableGeneratorTests.UCOWithSpecialCharacters - PInvokeTableGeneratorTests.BuildNativeInNonEnglishCulture Also refactor the existing inline copies in DllImportTests and IcuTestsBase to use the new helper. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The test loads WasmAppBuilder.dll from the Microsoft.NET.Runtime.WebAssembly.Sdk workload pack, which is not present in the CoreCLR-Wasm NoWorkload Helix payload, so the test fails with DirectoryNotFoundException there. Restrict it to the Mono pipeline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Note Generated by Copilot CLI. While triaging A.
|
| private const string s_nugetInsertionTag = "<!-- TEST_RESTORE_SOURCES_INSERTION_LINE -->"; | ||
|
|
||
| public static bool IsUsingWorkloads => s_buildEnv.IsWorkload; | ||
| public static bool IsUsingWorkloads => IsCoreClrRuntime || s_buildEnv.IsWorkload; |
| // Extract the runtime pack root that the build actually resolved (printed by | ||
| // BrowserWasmApp.targets / BrowserWasmApp.CoreCLR.targets as |
| /// <summary> | ||
| /// Replaces the project's wwwroot/main.js with a minimal version that just calls | ||
| /// runMainAndExit, without any JS interop calls (no setModuleImports / getAssemblyExports). | ||
| /// This is needed for tests whose managed program does not use JS interop, because on | ||
| /// CoreCLR-Wasm the trimmer drops System.Runtime.InteropServices.JavaScript when nothing | ||
| /// roots it, causing the template main.js to fail at startup with | ||
| /// Arg_TargetInvocationException out of JSHostImplementation.BindAssemblyExports. | ||
| /// </summary> | ||
| protected void ReplaceMainJsWithMinimalRunMain() | ||
| { | ||
| string mainJsPath = Path.Combine(_projectDir, "wwwroot", "main.js"); | ||
| File.Copy(Path.Combine(BuildEnvironment.TestAssetsPath, "EntryPoints", "icu_main.js"), mainJsPath, overwrite: true); | ||
| } |
| // [diag] Log DOTNET_CLI_HOME inherited by the `dotnet new <template>` invocation. | ||
| // The template engine reads installed templates from this location; if it differs | ||
| // from the DOTNET_CLI_HOME used by EnsureWasmTemplatesInstalled, the template | ||
| // won't be found. | ||
| string inheritedCliHome = Environment.GetEnvironmentVariable("DOTNET_CLI_HOME") ?? "<unset>"; | ||
| string envVarsCliHome = s_buildEnv.EnvVars.TryGetValue("DOTNET_CLI_HOME", out string? evCliHome) ? evCliHome : "<unset-in-EnvVars>"; | ||
| Console.WriteLine($"[diag] DOTNET_CLI_HOME inherited by `dotnet new {template.ToString().ToLower()}`: '{inheritedCliHome}' (buildEnv.EnvVars: '{envVarsCliHome}')"); |
Note
This PR description was AI-generated (GitHub Copilot CLI).
Follow-up to #127073. Now that WASM templates install and native relink work on CoreCLR in
Wasm.Build.Tests(WBT), enable the non-AOT tests that were previously excluded by the class-level[TestCategory("native")]trait filter.What changes
src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csprojexcludescategory=nativeon CoreCLR:xunit merges class-level and method-level traits, so moving
nativeto a sub-category (e.g.native-coreclr) at method level does not help — the class-levelnativestill causes exclusion. The fix is to remove the class-level tag and re-applynativeonly on the AOT-only methods.NativeBuildTests.csAOTNotSupportedWithNoTrimming,IntermediateBitcodeToObjectFilesAreNotLLVMIR,NativeBuildIsRequired(all AOT-only). Non-AOT methods (SimpleNativeBuild,ZipArchiveInteropTest) now run on CoreCLR.DllImportTests.csPInvokeTableGeneratorTests.csEnsureWasmAbiRulesAreFollowedInAOT,EnsureComInteropCompilesInAOT.NativeLibraryTests.cs[BuildAndRun(aot:false)]and[BuildAndRun(aot:true,…)]into a non-AOT method and an_AOTmethod taggednative(they delegate to a shared…Corehelper). The pre-existing[ActiveIssue(#103566)]onProjectUsingSkiaSharpis applied to both halves.Splitting (rather than runtime-skip) keeps test reporting honest: AOT-on-CoreCLR shows up as "excluded by filter" instead of a false pass.
Not in scope: other
[TestCategory("native")]classes in WBT (BuildPublishTests,NativeRebuildTests/*,WasmSIMDTests,IcuTests,SatelliteAssembliesTests, …). Those often encode reasons beyond "class-levelnativeis too broad" and are left for a follow-up.Validation
./dotnet.sh build src/mono/wasm/Wasm.Build.Tests/Wasm.Build.Tests.csproj -c Release /p:TargetOS=browser /p:RuntimeFlavor=CoreCLR /p:Scenario=BuildWasmApps→ 0W/0E.