Skip to content

Commit e523587

Browse files
docs(aot): expand selftest AOT skip list + document AOT test workflow
Iteration round against an AOT-published Host surfaced 16 new crasher patterns (or families) past the previous skip set. Bake them into DefaultAotSkipPatterns so a fresh AOT run completes without manual REACTOR_AOT_SKIP plumbing, and add a CONTRIBUTING subsection covering the publish command, where the binary lands, how to extend the skip list, and the current AOT pass headcount (544/735 pass, 149 skipped) so contributors aren't surprised. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9cb6898 commit e523587

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

CONTRIBUTING.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,49 @@ dotnet run --project tests/Reactor.AppTests.Host -- --self-test
137137
dotnet run --project tests/Reactor.AppTests.Host -- --self-test --filter "Flex"
138138
```
139139

140+
#### Running selftests under NativeAOT
141+
142+
The Host app supports an AOT-published build so the selftest suite doubles as Reactor's primary AOT regression gate. The framework itself is AOT-clean (see [`docs/aot-support.md`](docs/aot-support.md)) but a meaningful slice of selftest *fixtures* still trip over reflection paths the AOT compiler can't preserve. Those fixtures are pre-skipped via a baked-in pattern list so the run completes and the remaining failures are visible.
143+
144+
**1. Publish the Host with AOT.** The publish step shells out to MSVC's `link.exe`, so it must run inside a Visual Studio Developer environment. From a Developer Command Prompt / Developer PowerShell (or after sourcing `Launch-VsDevShell.ps1`):
145+
146+
```powershell
147+
dotnet publish tests/Reactor.AppTests.Host `
148+
-c Release -p:Platform=x64 -r win-x64 `
149+
-p:PublishAotInternal=true --self-contained
150+
```
151+
152+
`PublishAotInternal=true` is the internal opt-in property that flips `PublishAot` on for the Host (kept opt-in so an ordinary `dotnet build Reactor.slnx` doesn't pay the AOT compile cost). Swap `-r win-x64` / `-p:Platform=x64` for `win-arm64` / `ARM64` on ARM machines.
153+
154+
The published binary lands at:
155+
156+
```
157+
tests/Reactor.AppTests.Host/bin/x64/Release/net10.0-windows10.0.22621.0/win-x64/publish/Reactor.AppTests.Host.exe
158+
```
159+
160+
**2. Run the suite.** Same `--self-test` flag as the JIT build:
161+
162+
```bash
163+
./tests/Reactor.AppTests.Host/bin/x64/Release/net10.0-windows10.0.22621.0/win-x64/publish/Reactor.AppTests.Host.exe --self-test
164+
```
165+
166+
Output is the same TAP stream as a normal selftest run. The runner detects AOT at startup (`RuntimeFeature.IsDynamicCodeSupported == false`) and emits `# SKIP crashes/hangs under NativeAOT` lines for known-bad fixtures.
167+
168+
**3. Filtering known-bad fixtures.** The skip list lives in `DefaultAotSkipPatterns` in `tests/Reactor.AppTests.Host/SelfTest/SelfTestRunner.cs`. Entries are exact names or `Prefix*` wildcards. When you discover a new AOT crasher, you have two choices:
169+
170+
- **Without rebuilding** (best for iteration): append patterns via the `REACTOR_AOT_SKIP` env var. They merge into the defaults — they do *not* replace them.
171+
172+
```bash
173+
REACTOR_AOT_SKIP="MyFixture_Crasher,SomeFamily_*" \
174+
./.../Reactor.AppTests.Host.exe --self-test
175+
```
176+
177+
- **Permanent**: add the pattern to `DefaultAotSkipPatterns` and re-publish. Leave a comment naming the family / observed crash mode so a future contributor can verify whether the underlying issue has been fixed and drop the entry.
178+
179+
A native crash terminates the AOT process — the per-fixture managed watchdog can't fire. Iterate by tailing the TAP output for the *last* `# Running: <name>` line before exit, add that name to the skip list, and re-run. Be conservative when wildcarding a family: many `Family_*` fixtures pass even when one member crashes.
180+
181+
**4. Expected pass count.** As of 2026-05-20, an AOT run of the suite produces roughly: 735 fixtures total → 149 skipped, 544 passed, ~42 failed (assertion failures + initialization crashes for fixtures already past the skip filter). The non-AOT run on the same commit is 735/735 pass.
182+
140183
### 3. E2E tests (`tests/Reactor.AppTests`) — MSTest + WinAppDriver
141184

142185
End-to-end tests that use Appium/WinAppDriver to simulate real user input (clicks, keyboard, tab navigation) through the cross-process UI Automation pipeline. These verify the full input → render → output path and validate that UIA properties are visible to assistive technology.

tests/Reactor.AppTests.Host/SelfTest/SelfTestRunner.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,26 @@ internal static class SelfTestRunner
7777
"CoreCov2_XamlHostMount",
7878
"CoreCov2_InfoBadgeMountUpdate",
7979
"CoreCov2_SelectorBarUpdate",
80+
// Iteration round 2 (2026-05-20): crashers observed when re-running
81+
// selftests against an AOT-published Host. Same approach — skip the
82+
// crasher, then wildcard family members that are likely to share the
83+
// shape problem.
84+
"ValCov_FormFieldRendering",
85+
"EchoSuppress_*",
86+
"IdentityPreserve_RadioButtons",
87+
"IdentityPreserve_SelectorBar",
88+
"DataGrid_RowEditTemplatesAndEmptyState",
89+
"CovBoost_ElementPoolExercise",
90+
"CovBoost2_TitleBarMountUpdate",
91+
"CovBoost2_ReconcileChildPaths",
92+
"CovBoost2_NavigationViewExercise",
93+
"CovBoost2_ElementPoolInteractiveReset",
94+
"Commanding_*",
95+
"SelectionEvt_*",
96+
"ValueEvt_*",
97+
"Immediate_*",
98+
"Editors_*",
99+
"RBC_*",
80100
};
81101

82102
private static string[] GetAotSkipPatterns()

0 commit comments

Comments
 (0)