microsoft / microsoft/microsoft-ui-reactor

[Flaky] WindowLevel_RuntimeFlip_Topmost fails intermittently in the full selftest run

Open Beginner friendly
#927 2 comments 0 reactions 0 assignees View on GitHub
bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.