Skip to content

No packaged (MSIX) test tier — selftests run unpackaged and cannot catch identity-dependent bugs #1148

Description

Problem

The selftest suite (tests/Reactor.AppTests.Host) runs unpackaged. That makes it structurally blind to a class of bug where an API behaves differently under MSIX package identity — and we just shipped and then fixed exactly such a bug.

In #1145, WindowIcon.FromResource("ms-appx:///Assets/AppIcon.ico") passed its URI straight to AppWindow.SetIcon. Measured from inside a registered MSIX app:

SetIcon form Packaged result
ms-appx:///Assets/AppIcon.ico HICON=65579the same handle in two separate packaged processes, i.e. a shared system default
Assets\AppIcon.ico distinct real per-window handle
AppContext.BaseDirectory absolute distinct real per-window handle
Package.Current.InstalledLocation.Path absolute distinct real per-window handle

So the packaged path — the one FromResource exists to serve — silently applied a default icon.

The selftest fixture WindowModel_WindowIconApplied had a WindowIcon_FromResource_Sets_HICON check and it passed the whole time, because in an unpackaged process ms-appx: resolves against the executable directory and appears to work. The check was green and the feature was broken.

It was only caught by manually building and registering a real MSIX app and reading WM_GETICON back.

Why this matters beyond icons

Anything that consults package identity can diverge the same way:

  • PackageRuntime.IsPackaged gates real behaviour in JumpList (JumpList.cs:316), and the WindowIcon fallback path in ReactorWindow.
  • ms-appx: / ms-resource: URI resolution generally (Image sources, TitleBar.Icon, tray icons).
  • Windows.ApplicationModel.Package.Current (InstalledLocation, Logo), MRT / resources.pri lookup.
  • Jump lists, tray icons, and taskbar surfaces that behave differently with identity.

Every one of these is currently only exercised on the unpackaged arm, so the packaged arm is asserted nowhere.

Suggestion

Add a minimal packaged smoke tier. tests/startup_perf/BlankReactorMsix already proves a packaged Reactor app builds and registers in this repo, so most of the packaging work exists — it just isn't wired to any assertions.

Roughly:

  1. A small MSIX-packaged host that registers loose via Add-AppxPackage -Register AppxManifest.xml (developer mode; no signing needed).
  2. A handful of assertions that are only meaningful under identity — starting with WindowIcon.FromResource landing a real per-window HICON.
  3. A CI job that registers, runs, and unregisters it.

Non-vacuity requirement. The assertions must fail when run unpackaged, or the new tier reproduces the original problem in a new place. Concretely, a packaged check should assert against a distinct real handle rather than merely non-zero — the bug above produced a non-zero (but shared, default) handle, so a bare != 0 check would have passed straight through it.

Context

  • Found while manually testing Add first-class window icon to ReactorApp.Run (taskbar / alt-tab) #1145 across packaged/unpackaged × Debug/Release.
  • Fixed there by resolving ms-appx: to a filesystem path before calling SetIcon; WindowIconResourceUriTests covers the mapping, but only as a pure unit test.
  • Related: docs/guide/windows.md "Window icon" section documents the packaged/unpackaged split.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions