Skip to content

Reliability fixes for PackageDeploymentManager test - #6693

Merged
Vineeth Thomas Alex (vineeththomasalex) merged 4 commits into
release/dev/monobuildfrom
user/vithoma/fix-packagedeploymentmanager-test-isolation
Aug 18, 2026
Merged

Reliability fixes for PackageDeploymentManager test#6693
Vineeth Thomas Alex (vineeththomasalex) merged 4 commits into
release/dev/monobuildfrom
user/vithoma/fix-packagedeploymentmanager-test-isolation

Conversation

@vineeththomasalex

@vineeththomasalex Vineeth Thomas Alex (vineeththomasalex) commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Problem

221 of the ~228 transient failures on WinAppSDK-Test-Foundation (def 192441) stem from one test-isolation defect:

  • PackageDeploymentManagerTests_Register (190 failures — whole class cascades from ClassSetup/fixture failure with empty error text)
  • PackageDeploymentManagerTests_IsPackageRegistrationPending (21 of 28 failures)
  • PackageDeploymentManagerTests_IsReadyOrNewerAvailable (10 failures)

Reference runs:

Root cause (cascade)

Test::Packages::AddPackage() already retries AddPackageAsync up to 5 times with exponential backoff (~15s total) when it hits ERROR_PACKAGES_IN_USE (0x80073D02), but always reissues with DeploymentOptions::None.

RemovePackage_Blacker() / RemovePackage_Black() call into this exact AddPackage() path whenever the target package is staged-but-not-registered (they register it first so it can be removed). These helpers are called pervasively across PackageDeploymentManagerTests_Register, _IsPackageRegistrationPending, and _IsReadyOrNewerAvailable — including from TEST_CLASS_SETUP/TEST_CLASS_CLEANUP.

PackageDeploymentManagerTests_IsPackageRegistrationPending's *_Pending tests activate Test.PackageManager.M.Black (same package family as Blacker) and defer-register Blacker while it's running. A prior fix (#6678) added a wait for the activated process to exit, but the OS-side "in use" bookkeeping for the package family doesn't necessarily clear the instant the process handle signals — the deferred registration completing is a separate async step. When it hasn't settled by the time the next RemovePackage_Blacker() call fires (in the same class's cleanup, or the next class's setup), AddPackageAsync fails with 0x80073D02 again, and 5 retries at ~15s total isn't always enough. A single stuck call inside a TEST_CLASS_SETUP/TEST_CLASS_CLEANUP fixture fails the whole fixture, and TAEF cascades every test in the class to [Failed] with empty error text — and the leftover staged package repeats the same race in the next class that runs, which is why the cascade spans three classes.

Confirmed directly from the ADO test results for build 154915868 (IsPackageRegistrationPendingForUser_NotInstalled, _Registered, _Pending, and both IsReadyOrNewerAvailable failures all show the identical AddPackageAsync('...Blacker...') = 0x80073D02 ... Test.PackageManager.M.Black_1.2.3.4... failure at WindowsAppRuntime.Test.Package.h:459; all 38 Register::* tests fail with empty error text from the cascaded ClassSetup).

Fix 1: cascade fix (force-close on retry)

Once AddPackageAsync fails with ERROR_PACKAGES_IN_USE, escalate to DeploymentOptions::ForceTargetApplicationShutdown on the next retry so the deployment service force-closes the blocking process itself instead of guessing how long to wait — this is the option the platform documents for exactly this error ("If this package is currently in use, the processes associated with the package are shut down forcibly so that registration can continue."). The first attempt is left as DeploymentOptions::None so a clean install is never destructive; only a confirmed ERROR_PACKAGES_IN_USE failure escalates subsequent retries.

This is a single, universal choke point: every RemovePackage_Blacker()/RemovePackage_Black() call across all three affected test classes funnels through this same AddPackage() function, so the fix addresses the cascade regardless of which specific test left the package family "in use".

Fix 2: defensive hardening (bounded OpenEventW retry)

While investigating the 2 residual IsPackageRegistrationPending_Pending / IsPackageRegistrationPendingForUser_Pending failures (a separate, pre-existing, real product-behavior issue — see Scope below), an exhaustive local-VM investigation (raw FrameworkUdk export, compiled WinRT wrapper, native harness replicating the real test's exact call sequence, and finally the actual unmodified TAEF test binary end-to-end — all passed reliably) did not force-reproduce the CI-specific trigger. The most concrete candidate mechanism found was a fragile, non-retrying OpenEventW + RETURN_LAST_ERROR_IF_NULL pattern in the test apps' winmain.cpp (PackageManager.Test.M.Black.msix / PackageManager.Test.M.Blacker.msix) — a single missed/delayed event-open attempt fails the whole app launch with no retry.

Added a bounded retry (5s budget, 50ms poll interval) before falling back to the original behavior. This is defensive hardening for a plausible CI-environment-specific timing issue, not a proven fix for the _Pending issue — that issue remains open and out of scope (see below), but this change is safe, tested, and closes off one class of test-app-side flakiness regardless.

Scope

  • Test-infrastructure only (test/inc/WindowsAppRuntime.Test.Package.h, test/PackageManager/data/PackageManager.Test.M.{Black,Blacker}.msix/winmain.cpp). No product code changed.
  • Does not touch the separate, already-known IsPackageRegistrationPending_Pending / IsPackageRegistrationPendingForUser_Pending API-behavior assertion at IsPackageRegistrationPending.cpp:108 (API returns false for the pending state) — that's a real product-behavior issue investigated exhaustively (local VM: raw export, compiled wrapper, native harness, and the actual unmodified TAEF binary all pass reliably) but not root-caused; it's a separate, real, CI-environment-specific issue tracked for future work, out of scope per the original task.
  • ABForward::FunctionalTests::ClassInit (2 failures) is a separate fixture, not addressed here.

Verification — real CI, real source-built IXP, twice

Validated via the monobuild's targeted rebuild-stage mechanism (useBuildOutput_RebuildStage=Foundation), which rebuilds Foundation from this branch against a prior monobuild run's already-source-built InteractiveExperiences (LiftedIXP/FrameworkUdk) artifacts, then auto-triggers a real WinAppSDK-Test-Foundation (def 192441) run — without triggering a full monobuild.

Cascade fix alone: producer build 155077760 → test build 155084977.

Combined (cascade fix + hardening, this branch's current state): producer build 155179455 → test build 155187907.

Result (both runs, identical): 228 → 14 total individual test failures across all 12 configs, queried directly via the Test Results API:

Config Failed
7 configs (24H2, 25h2, 25H2.zh-CN, MultiSession, Server2025, LTSC 2021, Win10 22H2 x86) 2 each — both IsPackageRegistrationPending_Pending / ...ForUser_Pending (pre-existing, known, out-of-scope — see above)
5 configs (Server2019.zh-CN, Win10 rs5, 3× arm64) 0
Total 14

Zero 0x80073D02 and zero Register::ClassSetup failures anywhere across all 12 configs — confirmed by scanning every failed-test's title and error message.

Also independently validated via WinAppSDK-Foundation-PR (def 189940, builds from PR merge ref against a pinned/NuGet IXP dependency — proves no regression, though it doesn't exercise the source-built-IXP condition): 0/12 configs failed for both the cascade fix alone and the combined branch. And via local VM: the actual unmodified TAEF PackageManagerTests.dll, real MSIX packages, real Framework/DataStore/LifetimeManager packages, and real bootstrap infrastructure — all built from source and run end-to-end, 8/8 tests passing in the affected class.

…n ERROR_PACKAGES_IN_USE retry

Test::Packages::AddPackage() retries AddPackageAsync up to 5 times with
exponential backoff (~15s total) when it hits ERROR_PACKAGES_IN_USE
(0x80073D02), but always reissues with DeploymentOptions::None. When an
earlier test's activated app (e.g. IsPackageRegistrationPending_Pending's
Test.PackageManager.M.Black instance) hasn't fully released its package
lock within that window -- or a deferred registration from a prior test
hasn't completed settling -- every retry fails identically and the
in-place upgrade to Test.PackageManager.M.Blacker never makes progress.

RemovePackage_Blacker()/RemovePackage_Black() call into this same
AddPackage() path whenever the target package is staged-but-not-registered
(to register it before removal), and are invoked pervasively across
PackageDeploymentManagerTests_Register, _IsPackageRegistrationPending, and
_IsReadyOrNewerAvailable -- including from TEST_CLASS_SETUP/TEST_CLASS_CLEANUP.
A single stuck AddPackage() there fails the fixture and TAEF cascades every
test in the class to [Failed] with empty error text, then the leftover
staged package repeats the same race in the next class that runs.

Fix: once AddPackageAsync fails with ERROR_PACKAGES_IN_USE, escalate to
DeploymentOptions::ForceTargetApplicationShutdown on the next retry so the
deployment service force-closes the blocking process itself instead of us
guessing how long to wait -- this is the option the platform documents for
exactly this error. The first attempt is left as DeploymentOptions::None
so a clean install is never destructive.

This should eliminate the 0x80073D02 cascade behind ~221 failures in
Test-Foundation (PackageDeploymentManagerTests_Register,
_IsPackageRegistrationPending, _IsReadyOrNewerAvailable). It does not
change the unrelated, already-known IsPackageRegistrationPending_Pending
API-behavior assertion at IsPackageRegistrationPending.cpp:108.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7a243429-2b18-4b9a-aea2-f207cc2ea908
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Add a short note to the AddPackage() comment clarifying that the
escalation can only ever close a process left over from an earlier,
already-finished test - no test installs the package it's actively
exercising via this helper while that app is running (confirmed: the
IsPackageRegistrationPending "_Pending" tests exercise the in-use/deferred
scenario through AddPackageByUri's DeferRegistrationWhenPackagesAreInUse
path, which this change doesn't touch) - and that unconditional use of
ForceApplicationShutdown in Shared.cpp's and TestSetupAndTeardownHelper.h's
InstallPackage() helpers is existing precedent for this exact mitigation
in this test suite.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7a243429-2b18-4b9a-aea2-f207cc2ea908
@vineeththomasalex

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.

…er/vithoma/fix-packagedeploymentmanager-test-isolation
@vineeththomasalex Vineeth Thomas Alex (vineeththomasalex) changed the title Fix PackageDeploymentManager test cascade: force-close blocking app on ERROR_PACKAGES_IN_USE retry Fix PackageDeploymentManager test cascade + harden test-app event wait Aug 18, 2026
@vineeththomasalex

Copy link
Copy Markdown
Collaborator Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
1 pipeline(s) were filtered out due to trigger conditions.

@vineeththomasalex Vineeth Thomas Alex (vineeththomasalex) changed the title Fix PackageDeploymentManager test cascade + harden test-app event wait Reliability fixes for PackageDeploymentManager test Aug 18, 2026
@vineeththomasalex
Vineeth Thomas Alex (vineeththomasalex) marked this pull request as ready for review August 18, 2026 21:10
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@vineeththomasalex
Vineeth Thomas Alex (vineeththomasalex) merged commit 3b1f049 into release/dev/monobuild Aug 18, 2026
44 of 46 checks passed
@vineeththomasalex
Vineeth Thomas Alex (vineeththomasalex) deleted the user/vithoma/fix-packagedeploymentmanager-test-isolation branch August 18, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants