microsoft / microsoft/microsoft-ui-reactor
[Flaky] WindowLevel_RuntimeFlip_Topmost fails intermittently in the full selftest run
- Dominant language
- C#
- Stars
- 646
- Forks
- 54
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 84
Description
## Summary
`WindowLevel_RuntimeFlip_Topmost` (`Phase4WindowingFixtures.WindowLevelRuntimeFlip`) fails intermittently — roughly **1 run in 3** — but only in the *full* selftest run. It passes 100% of the time when the fixture is run in isolation.
This intermittently reddens CI for unrelated PRs, and because the failure is a plain `assertion failed` with no context it costs time to re-triage each time someone hits it.
## Evidence
Observed while validating an unrelated branch (#925). Confirmed against **clean `origin/main` @ bafeeba9**, with no local changes, so this is not branch-specific:
| Target | Command | Result |
|---|---|---|
| `origin/main` | full `--self-test` | pass |
| `origin/main` | full `--self-test` | pass |
| `origin/main` | full `--self-test` | **fail** |
| feature branch | full `--self-test` | fail, fail, then pass |
| either | `--self-test --filter "WindowLevel"` | pass, 5/5 checks, every time |
Isolation passing while the full run fails points at cross-fixture interference — most likely residual Z-order or foreground-window state from a preceding windowing fixture — rather than anything wrong with the assertion itself.
## The failing assertion
`tests/Reactor.AppTests.Host/SelfTest/Fixtures/Phase4WindowingFixtures.cs:249`
```csharp
win.Update(spec with { Level = WindowLevel.AlwaysOnTop });
await Harness.Render(80);
H.Check("WindowLevel_RuntimeFlip_Topmost", (ExStyleBits(win) & Native.WS_EX_TOPMOST) != 0);
```
The paired `WindowLevel_RuntimeFlip_Normal` check immediately after has never been observed failing.
## Suspected cause
`await Harness.Render(80)` is a fixed 80 ms wait for the `WS_EX_TOPMOST` ex-style bit to appear after `Update`. The style change goes through `SetWindowPos` on the native window; under a loaded full-suite run (many windows opened/closed by preceding fixtures) 80 ms is evidently not always enough. The neighbouring fixtures in the same file use `Harness.WaitFor(...)` with retries for exactly this kind of native-state settle:
```csharp
bool above = await Harness.WaitFor(() => IsAbove(floating, owner), maxPasses: 10, perPassMs: 40);
```
## Suggested fix
Replace the fixed delay with the polling helper already used by its siblings:
```csharp
win.Update(spec with { Level = WindowLevel.AlwaysOnTop });
bool topmost = await Harness.WaitFor(
() => (ExStyleBits(win) & Native.WS_EX_TOPMOST) != 0, maxPasses: 10, perPassMs: 40);
H.Check("WindowLevel_RuntimeFlip_Topmost", topmost);
```
Same for the `Normal` half, so the pair stays symmetric. This keeps the assertion just as strict — it still fails if the bit never flips — while removing the dependence on a single fixed timing window.
Worth checking whether other fixed-delay assertions on native window state have the same latent issue.
## Repro
```
dotnet build tests/Reactor.AppTests.Host -c Debug -p:Platform=x64
dotnet run --project tests/Reactor.AppTests.Host --no-build -c Debug -p:Platform=x64 -- --self-test
```
Run 3–4 times; expect at least one `not ok WindowLevel_RuntimeFlip_Topmost - assertion failed`.
Note this reproduces on a developer machine; whether the CI runner hits the same rate is unconfirmed.
Contributor guide
Research direction
Start at tests/Reactor.AppTests.Host/SelfTest/Fixtures/Phase4WindowingFixtures.cs:249 and compare the fixed Render delay with neighbouring WaitFor usage. Run the provided dotnet build and full --self-test commands repeatedly, also checking the filtered fixture. Done means both RuntimeFlip checks use polling for native state and the full self-test no longer intermittently fails.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- desktop, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100