Skip to content

Add RFC 017: Custom test host process launcher#9349

Draft
Evangelink wants to merge 3 commits into
mainfrom
docs/rfc-testhost-process-launcher
Draft

Add RFC 017: Custom test host process launcher#9349
Evangelink wants to merge 3 commits into
mainfrom
docs/rfc-testhost-process-launcher

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Adds RFC 017 — Custom test host process launcher (docs/RFCs/017-TestHost-Process-Launcher.md).

The RFC proposes a public, experimental MTP extension point — ITestHostProcessLauncher — that lets an extension control how the out-of-process test host is launched, instead of the platform always calling Process.Start. The platform keeps owning everything around the launch (argument/environment preparation, the controller↔host IPC pipe, PID tracking, ITestHostProcessLifetimeHandler callbacks, and exit-code reconciliation) and delegates only the single "create the process" step.

The motivating scenario is testing packaged WinUI/MSIX apps, which must be AUMID-activated rather than Process.Start-ed (the blocker behind #2784). The hook is deliberately generic and the RFC includes worked examples for:

  • Packaged WinUI/MSIX (AUMID activation)
  • Launching under a debugger (start suspended + attach/resume)
  • Elevated (runas, incl. the env-var caveat)
  • Container (docker run)
  • Remote (SSH)

It also covers the exact platform integration site (TestHostControllersTestHost), forcing the controller host via RequireProcessRestart, a minimal PID-only API variant, why ITestHostExecutionOrchestrator is the wrong layer, and the repo conventions ([Experimental("TPEXP")], PublicAPI.Unshipped.txt, no init).

Docs-only; no code changes. Opening as a draft to gather design feedback.

Related: #2784

Proposes an experimental ITestHostProcessLauncher MTP extension point that lets an extension control how the out-of-process test host is launched (replacing Process.Start), enabling packaged WinUI/MSIX (AUMID activation, #2784), debugger, elevated, container, and remote launch scenarios.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 22, 2026 17:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new design document (RFC 017) proposing an experimental Microsoft.Testing.Platform extension point (ITestHostProcessLauncher) to let extensions customize how the out-of-process test host is launched, while keeping platform-owned responsibilities (args/env prep, IPC, lifetime handling, exit reconciliation) unchanged.

Changes:

  • Introduces RFC 017 documentation describing the proposed ITestHostProcessLauncher API surface and registration shape.
  • Documents intended platform integration points (controller host selection, launch-site delegation, singleton enforcement).
  • Provides worked examples (WinUI/MSIX activation, debugger attach, elevation, container, remote) plus alternatives and open questions.
Show a summary per file
File Description
docs/RFCs/017-TestHost-Process-Launcher.md New RFC describing an experimental extension point for customizing out-of-process test host process launching.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 4

Comment thread docs/RFCs/017-TestHost-Process-Launcher.md Outdated
Comment thread docs/RFCs/017-TestHost-Process-Launcher.md Outdated
Comment thread docs/RFCs/017-TestHost-Process-Launcher.md Outdated
Comment thread docs/RFCs/017-TestHost-Process-Launcher.md Outdated
Evangelink and others added 2 commits June 23, 2026 09:09
- Fix TestHostOchestratorHost -> TestHostOrchestratorHost type name (the file name has the typo, the type does not)
- SSH example: EnvironmentVariables values are nullable; skip unset (null) vars instead of Quote(null)
- WinUI example: drop unnecessary async (no await) to avoid CS1998; return Task.FromResult
- Clarify #2784 relationship: it is titled for unpackaged WinUI, but this launcher serves both packaged (AUMID) and unpackaged WinUI scenarios

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The 'Alternatives' link pointed to #alternatives but the heading is 'Alternatives considered' (#alternatives-considered).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 24, 2026 08:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 5

using IProcess testHostProcess = process.Start(processStartInfo);
```

Everything downstream only needs five things from the returned handle — `Id`, the `Exited` event, `WaitForExitAsync()`, `ExitCode`, and `Kill()` — plus the child connecting back on the named pipe whose name was injected via an environment variable. **`Process.Start` is the only assumption that does not hold universally.** Several real scenarios need a different launch mechanism:
Comment on lines +179 to +182
// 2. Activate, passing the SAME args the platform prepared.
var aam = (IApplicationActivationManager)new ApplicationActivationManager();
aam.ActivateApplication(aumid, string.Join(' ', context.Arguments),
ACTIVATEOPTIONS.AO_NONE, out uint pid);

### 1. Packaged WinUI / MSIX (the motivating case)

Activate the packaged app by AUMID instead of starting an exe. The activated app self-hosts MTP (as the `MSTestRunnerWinUI` sample already does) and connects back on the env-provided pipe.

### Contract requirements on the launcher

- The launched process **must** be a real OS process with a queryable PID, it **must** inherit/receive `context.EnvironmentVariables` (so it connects back on the controller pipe), and it **must** be passed `context.Arguments`.
Comment on lines +184 to +185
// 3. Wrap the returned PID. The app inherits context.EnvironmentVariables
// (incl. the MONITORTOHOST pipe name) via its activation/launch profile.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants