Repository navigation
[wasi] Add CoreCLR ReadyToRun library and runtime test CI - #134813
Merged
Merged
Conversation
|
Azure Pipelines: Successfully started running 7 pipeline(s). 9 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
lewing
marked this pull request as draft
September 28, 2026 19:57
Contributor
|
Tagging subscribers to this area: @dotnet/area-infrastructure-libraries |
Contributor
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
lewing
added a commit
that referenced
this pull request
Sep 29, 2026
## Summary Enable composite ReadyToRun (R2R) publishing for CoreCLR on WASI. This builds on the self-installing WebCIL R2R images from #134312, which is now in `main`. Per review feedback, this PR covers publishing and composition only. The WASI R2R runtime-test and trimmed library-test CI lanes, their test harness plumbing, and the related library test quarantines are in #134813, which is stacked on this PR. ## Implementation - The WASI app builder compiles the app and framework closure into a composite R2R image plus per-assembly forwarding stubs using Crossgen2. The per-app WASI host (`wasihost`) reserves an image buffer and function-table slice sized to that composite, and exports the symbols the composite imports. - A C# `ComposeWasiReadyToRun` WasmAppBuilder task composes the self-installing composite into the linked host component. It reuses the WebCIL reader infrastructure, and uses `wasm-tools` and Binaryen for the post-link merge and global folding. Crossgen2's finished R2R Wasm is not a relocatable `wasm-ld` input, so this step cannot move into the native link. Before merging, the task checks the image buffer size and the table reservation against the host's exported values. - The `wasihost` external assembly probe serves the embedded composite and the per-assembly WebCIL stubs that are extracted at build time. - In-tree publishing acquires pinned `wasm-tools`/Binaryen versions into the shared wasm tool cache (`eng/AcquireWasiR2RTools.targets`). - Docs: `docs/workflow/building/coreclr/wasi-r2r.md` and a WASI host composition section in `docs/design/mono/webcil.md`. ## Validation - `./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release`: 0 warnings, 0 errors. - Clean `PublishTrimmed` + `PublishReadyToRun=true` publish of `src/mono/sample/wasi/console` with an empty tool cache. The pinned tools were acquired, composition succeeded, and the app ran under wasmtime. `DOTNET_ReadyToRunLogFile` showed `Ready to Run initialized successfully` for all six loaded assemblies (CoreLib, the app, System.Runtime, System.Console, System.Threading, System.Runtime.InteropServices). - A non-R2R CoreCLR WASI publish of the same sample still links against the weak placeholder buffer and runs. Related: #130129. Follow-up: #134813. > [!NOTE] > This pull request description was prepared with assistance from GitHub Copilot. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 919fdde7-f547-4bfb-86ad-7ac02c626980
lewing
marked this pull request as ready for review
September 29, 2026 01:06
lewing
force-pushed
the
lewing-wasi-r2r-test-standup
branch
from
September 29, 2026 01:34
d1da103 to
2eae854
Compare
This was referenced Sep 29, 2026
This was referenced Sep 30, 2026
Open
WASI SDK 34 (dotnet#134992) includes the wasi-libc pread fix (WebAssembly/wasi-libc#862) for the memory corruption tracked by dotnet#134957. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Since the move to wasmtime 49/wasi-sdk 34, Dns.GetHostAddressesAsync on WASI sends an IP literal with a mismatched family to getaddrinfo, which now fails with EAI_NONAME (dotnet#135030). Split DnsGetHostAddresses_IPStringAndIncorrectFamily_ReturnsNoIPs into sync and async theories so only the async rows are quarantined on WASI; the sync rows keep running there. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Every test in the class needs SocketsHttpHandler, so use ConditionalClass(SocketsHttpHandler.IsSupported) instead of repeating the condition on each test. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Passes with the current main (JIT Wasm finally fixes); validated in a trimmed WASI R2R build. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…I tests Mirror the browser/Apple mobile trimming fixes for the trimmed WASI R2R lane: System.Composition and System.Data.Common descriptors, the DefaultValue/ DesignerHost override, a DateTime root for dynamic conformance tests, and root SqlMetaData so FacadeTest's forwarder survives trimming. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
DataSet XML tests gated on DataSetXmlSerializationIsSupported (dotnet#134954: the predicate can't see the trimmed switch because wasihost doesn't read runtimeconfig), plus System.ComponentModel.Composition.Tests and two Binder tests that browser/Apple already disable under trimming (dotnet#135045). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Mirror dotnet#134920 for WASI: run the full trimmed ReadyToRun library tests in the runtime-libraries-coreclr outerloop (Linux) instead of the scheduled runtime-extra-platforms run, keep the manual runtime-wasm-libtests path, and restore smoke-only for the PR lane. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
With File.Copy fixed, the constructor now fails because it copies the test
assembly from Environment.CurrentDirectory ('/') while the bundle lives under
/managed.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
System.Runtime.Tests and System.Xml.XmlSerializer.ReflectionOnly.Tests opt into OverrideDefaultValueAndDesignerHostSupport only for Apple mobile. Trimmed WASI apps substitute DefaultValueAttribute.IsSupported to false while the tests' AppContext-based predicates still report it as supported, so extend the opt-in to WASI. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- BFloat16 conversions from Int128/UInt128 on wasm ReadyToRun (dotnet#135116). - TensorPrimitives.Tan range reduction on wasm with accelerated Vector128 (dotnet#135117). - DataContractSerializer DataSet round trip under the trimmed DataSet switch (dotnet#134954). - Exclude System.Text.Json and System.Text.RegularExpressions tests from the WASI ReadyToRun lane: wasmtime is OOM-killed at startup (dotnet#135118). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
System.Runtime.Intrinsics doesn't exist on net481, where the wasm predicate is always false. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing
force-pushed
the
lewing-wasi-r2r-test-standup
branch
from
October 3, 2026 03:25
10b5618 to
d5648a7
Compare
Member
Author
|
/azp run runtime-libraries-coreclr outerloop |
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
maraf
approved these changes
Oct 5, 2026
Member
Author
|
/ba-g ssl failure is known |
This was referenced Oct 5, 2026
springmin
added a commit
to springmin/runtime-ohos
that referenced
this pull request
Oct 6, 2026
…ARSE-FIX-134813; 6 refs + dedup path all CLEAN)
lewing
added a commit
that referenced
this pull request
Oct 6, 2026
) #134964 makes wasihost pass the app's runtimeconfig properties to the runtime, which fixes #134954. This removes the 28 WASI `ActiveIssue` quarantines against #134954 that #134813 added. The re-enabled tests depend on AppContext switches: - System.Data.Common and System.Runtime.Serialization.Xml: DataSet XML serialization (`DataSetXmlSerializationIsSupported` now sees the trimmed switch value) - System.Diagnostics.DiagnosticSource switch tests: Activity ID format - System.Globalization.Calendars switch tests: Japanese calendar date parsing - System.Runtime.InvariantTimezone: `IsInvariant` - System.Text.Encoding: UTF-7 and code page/encoding name tests ## Validation Run locally on macOS arm64 with wasmtime 49.0.1, against a CoreCLR WASI Release product built from the base that #134813 merged on. Commands were `./dotnet.sh build <test.csproj> /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release`, plus `/p:TestWasmReadyToRun=true /p:EnableAggressiveTrimming=true` for the trimmed composite R2R lane. | Suite | Interpreter | Trimmed composite R2R | |---|---|---| | System.Data.Common.Tests | 11,661 run, 0 failed | 11,281 run, 0 failed | | System.Diagnostics.DiagnosticSource.Switches.Tests | 4 run, 0 failed | 4 run, 0 failed | | System.Runtime.Serialization.Xml.Tests | 341 run, 0 failed | 341 run, 0 failed | | System.Globalization.CalendarsWithConfigSwitch.Tests | 1 run, 0 failed | 1 run, 0 failed | | System.Runtime.InvariantTimezone.Tests | 36 run, 0 failed | 36 run, 0 failed | | System.Text.Encoding.Tests | 14,612 run, 0 failed | 14,564 run, 0 failed | The only DiagnosticSource skip is `IdGenerationInternalParent`, which requires multithreading. > [!NOTE] > This PR description was generated with GitHub Copilot. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
lewing
added a commit
that referenced
this pull request
Oct 6, 2026
…bdirectory work (#134958) <!-- --> wasi-libc provides neither `mkstemps`/`mkstemp` nor `mkdtemp`. So on WASI, `SystemNative_MksTemps` asserted and returned `-1` without setting `errno`, and `SystemNative_MkdTemp` returned `NULL` the same way. As a result, `Path.GetTempFileName` threw `IOException : Success : '/tmp/'`, and `Directory.CreateTempSubdirectory` was also broken. The temp directory itself works fine; the only missing piece was creating a unique name in it. ## Change `src/native/libs/System.Native/pal_io.c`, WASI only. This mirrors how libc implements these functions: - `GetTempNameRandomChars` validates the template. It requires six `X` characters immediately before the suffix and otherwise fails with `errno = EINVAL`. - `FillTempNameRandomChars` fills the `XXXXXX` from `getentropy` (backed by `wasi:random`), mapped to `[A-Za-z0-9]`. - `SystemNative_MksTemps` loops up to 100 times calling `open(path, O_RDWR | O_CREAT | O_EXCL | O_CLOEXEC, 0600)`. It returns the fd on success, retries on `EEXIST`, and returns `-1` with `errno` preserved on any other error. If every attempt collides, it fails with `errno = EEXIST`. - `SystemNative_MkdTemp` runs the same loop with `mkdir(path, 0700)`. It returns the template on success and `NULL` with `errno` set on failure. Non-WASI native code paths are unchanged. The WASI preprocessor branch also uses `defined(TARGET_WASI)`. Because this lives in the shared System.Native, the fix applies to both CoreCLR and Mono on WASI. After #134813 merged, this branch was rebased onto upstream main `fa693c42fb6`. It removes all **89 WASI `ActiveIssue` attributes against #134943 across 24 test files**, preserving other attributes, comments, and test code. Removing the class-wide configuration quarantine exposed a separate missing-user-profile failure. Only `ConfigurationTests.TouchingFileWillReloadForUserSecrets` remains quarantined on WASI, now against #135225. No harness defaults or unrelated product code change in this PR. ## Validation after rebase and quarantine removal Local macOS arm64 host, wasi-sdk 34, wasmtime via XHarness, **CoreCLR WASI interpreter** (not ReadyToRun). The worktree-local tool-cache override avoids modifying a concurrently used checkout. The product command below passed with **0 warnings and 0 errors**. Initially the existing CMake caches retained SDK-33 compiler paths despite selecting the SDK-34 toolchain and failed to link WASI networking symbols. Clearing only this worktree's generated WASI CoreCLR/native object directories resolved the mismatch; no source workaround was used. ```sh export DOTNET_WASM_TOOL_CACHE_DIR="$PWD/.dotnet/wasm-tools" ./build.sh -os wasi -arch wasm -rf CoreCLR -s clr+libs+host+packs -c Release ./dotnet.sh build src/libraries/Microsoft.Extensions.Configuration.FileExtensions/tests/Microsoft.Extensions.Configuration.FileExtensions.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/Microsoft.Extensions.Configuration/tests/FunctionalTests/Microsoft.Extensions.Configuration.Functional.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/Microsoft.VisualBasic.Core/tests/Microsoft.VisualBasic.Core.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.CodeDom/tests/System.CodeDom.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.ComponentModel.Composition/tests/System.ComponentModel.Composition.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Data.Common/tests/System.Data.Common.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Diagnostics.TextWriterTraceListener/tests/System.Diagnostics.TextWriterTraceListener.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Private.Xml/tests/System.Private.Xml.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Reflection.Metadata/tests/System.Reflection.Metadata.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.Runtime.Loader/tests/RefEmitLoadContext/System.Runtime.Loader.RefEmitLoadContext.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release WasmXHarnessMonoArgs='--env=DOTNET_CI=true' ./dotnet.sh build src/libraries/System.Runtime/tests/System.IO.Tests/System.IO.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ./dotnet.sh build src/libraries/System.ServiceModel.Syndication/tests/System.ServiceModel.Syndication.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release ``` All commands above exited 0. Counts were checked in the runner logs and xUnit XML: | Suite | Run | Passed | Failed | Skipped | |---|---:|---:|---:|---:| | Microsoft.Extensions.Configuration.FileExtensions.Tests | 20 | 20 | 0 | 0 | | Microsoft.Extensions.Configuration.Functional.Tests | 32 | 29 | 0 | 3 | | Microsoft.VisualBasic.Core.Tests | 22,219 | 22,215 | 0 | 4 | | System.CodeDom.Tests | 5,982 | 5,977 | 0 | 5 | | System.ComponentModel.Composition.Tests | 1,431 | 1,426 | 0 | 5 | | System.Data.Common.Tests | 11,717 | 11,708 | 0 | 9 | | System.Diagnostics.TextWriterTraceListener.Tests | 132 | 130 | 0 | 2 | | System.Memory.Data.Tests | 87 | 81 | 0 | 6 | | System.Private.Xml.Tests | 48,626 | 48,558 | 0 | 68 | | System.Reflection.Metadata.Tests | 880 | 869 | 0 | 11 | | System.Runtime.Loader.RefEmitLoadContext.Tests | 1 | 1 | 0 | 0 | | System.IO.Tests | 3,019 | 2,963 | 0 | 56 | | System.ServiceModel.Syndication.Tests | 1,323 | 1,323 | 0 | 0 | | **Total** | **95,469** | **95,300** | **0** | **169** | `System.ComponentModel.Composition.Tests` was exercised in the interpreter lane, even though it is excluded from the trimmed WASI R2R lane (#135045). Two initial-run findings: - Configuration Functional initially reported **33 run, 29 passed, 1 failed, 3 skipped**: the missing `HOME` failure now tracked in #135225. A diagnostic re-run of the unquarantined bundle with guest `HOME=/tmp` reported **33 run, 30 passed, 0 failed, 3 skipped**. The final normal-environment run after the method-only quarantine reported the 32-test result above; 27 tests in `ConfigurationTests` still passed. - System.IO initially reported **3,020 run, 2,963 passed, 1 failed, 56 skipped**, solely in the unchanged `MemoryStream_CapacityBoundaryChecks` large-allocation test. That test already carries `SkipOnCI`; forwarding the existing CI guest setting `DOTNET_CI=true` reproduces the interpreter CI lane and gives the passing result above. No new MemoryStream quarantine was added, and all eight re-enabled StreamReader/StreamWriter temporary-file cases passed. ### Original before/after reproduction Before the test-standup merge, on the SDK-33 baseline: ```sh ./build.sh -os wasi -arch wasm -rf CoreCLR -s clr+libs -c Release ./build.sh -os wasi -arch wasm -rf CoreCLR -s libs.native -c Release ./dotnet.sh build src/libraries/System.Memory.Data/tests/System.Memory.Data.Tests.csproj /t:Test /p:TargetOS=wasi /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Release /p:TargetFramework=net11.0 ``` The product build passed with zero warnings/errors. Stashing the native fix, rebuilding `libs.native`, and running Memory.Data reproduced **87 run, 80 passed, 1 failed, 6 skipped** (`BinaryDataTests.CanCreateBinaryDataFromFileStream`: `IOException : Success : '/tmp/'`). Restoring the fix, rebuilding `libs.native`, and repeating the same test command passed: **87 run, 81 passed, 0 failed, 6 skipped**. The per-app wasihost links `libSystem.Native.a` from the runtime pack, so the rebuilt library is what the tests use. `System.Runtime.Extensions.Tests` (`PathTests.GetTempFileName`) and `System.IO.FileSystem.Tests` (`Directory_CreateTempSubdirectory`) do not target WASI (`-windows;-unix;-browser` only), so they were not run. Mono WASI and the ReadyToRun lane were not run. Resolves #134943 > [!NOTE] > This PR was authored with assistance from GitHub Copilot. --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds test coverage and CI for CoreCLR WASI composite ReadyToRun (R2R), now based directly on
mainafter the publishing support merged in #133265. The CI lanes and the test guards they depend on stay together so the coverage is self-contained.Changes
R2R_CG2runtime-test job.LibraryTestsCoreCLR_WASI_R2Rjob that runs a trimmed composite R2RSystem.Collections.Testssmoke suite.APP_ASSEMBLIES=EXTERNALandTEST_READY_TO_RUN_MODE=1passed to the guest.IsBrowsertoIsWasmwhere the tracking issue applies to all WebAssembly targets.Validation
After rebasing onto
main:./build.sh -s clr+libs+packs -os wasi -arch wasm -c Release: 0 warnings, 0 errors../build.sh -s clr+libs+packs -os wasi -arch wasm -c Checked: 0 warnings, 0 errors.git diff --checkpassed.Functional validation completed before opening this PR:
System.Collections.Tests: 33,958/33,958 passed.Ready to Run initialized successfullyentries, confirming R2R activation rather than interpreter fallback.Related: #130129.
Note
This pull request description was prepared with assistance from GitHub Copilot.