Skip to content

Default TRX to controller-backed recovery - #10808

Merged
Amaury Levé (Evangelink) merged 9 commits into
mainfrom
dev/amauryleve/trx-controller-recovery
Aug 28, 2026
Merged

Amaury Levé (Evangelink) merged 9 commits into
mainfrom
dev/amauryleve/trx-controller-recovery

Conversation

@Evangelink

@Evangelink Amaury Levé (Evangelink) commented Aug 27, 2026 •

Copy link
Copy Markdown
Member

Fixes #10792

Depends on #10797 (prerequisite timeout-lifecycle work; currently at 656b949fbd789cd923d6aa8bc29ea259d0b4d55b). This branch is based on main directly and does not copy #10797's timeout changes — it only needs the eventual controller-finalization behavior that PR provides, not any of its diff.

Summary

Run TRX in controller-backed mode whenever the platform supports a test-host controller. --report-trx alone now consistently selects the reliable controller-backed implementation on supported platforms — no --trx-mode option, no in-process opt-out, and no new CLI surface.

This does not move normal per-test TRX generation into the controller. The test host continues streaming and generating the report; the surviving controller owns recovery when the child exits before finalization.

Changes

  • TrxModeHelpers.IsTestHostControllerSupported replaces the old --crashdump gate as the signal used by the controller-registration side (TrxProcessLifetimeHandler, TrxEnvironmentVariableProvider, TrxReportExtensions.AddTrxReportProvider) to require/enable controller-backed TRX whenever the platform can launch a test-host process (excludes browser, iOS, tvOS, WASI).
  • TrxModeHelpers.ShouldUseOutOfProcessTrxGeneration (used inside the test host / child process) now checks the actual PlatformCommandLineProvider.TestHostControllerPIDOptionKey controller-presence state instead of assuming which extension caused isolation — so it correctly reflects reality when combined with HangDump, --timeout, etc.
  • The existing in-process implementation remains the automatic compatibility fallback on browser/iOS/tvOS/WASI, where process restart is unavailable.
  • Updated the "In process" → "Out of process" artifact-heading expectations in TrxTests.cs and TrxDataRowTests.cs to reflect the new default, and dropped the now-unnecessary --crashdump flag from the crash/timeout/handshake acceptance tests (plain --report-trx is now sufficient).
  • Added Trx_WhenOnlyReportTrxIsSpecified_UsesControllerBackedRecoveryByDefault as explicit acceptance coverage proving plain --report-trx goes through the controller on supported platforms, and TrxModeHelpersTests unit coverage for the new controller-presence logic.

Validation

  • .\build.cmd -c Debug — warning-clean build.
  • .\build.cmd -pack -c Release — warning-clean pack.
  • Unit tests: Microsoft.Testing.Extensions.UnitTests TRX-related tests on net8.0 and net462 — all pass (154/154 and 152/152 respectively), including the new TrxModeHelpersTests.
  • Acceptance tests (net462/net8.0/net10.0): TrxTests + TrxDataRowTests — 43/44 pass. The one failure (Trx_WhenReportTrxAndResultsDirectoryAreSpecifiedWithArtifact_ArtifactIsCopiedUnderRelativeResultsDirectory on net462) is a pre-existing, environment-specific PathTooLongException caused by this worktree's long checkout path exceeding Windows MAX_PATH on .NET Framework; reproduced identically with the production-code change reverted, so it is unrelated to this PR.
  • BrowserWasmExecution_TrxReport_RunsWithoutPlatformNotSupported — still passes, confirming the automatic in-process fallback on browser-wasm is unaffected.

- Make plain `--report-trx` use controller-backed recovery whenever the
  current platform supports launching a test-host process, by having
  TrxProcessLifetimeHandler/TrxEnvironmentVariableProvider require
  isolation whenever TrxModeHelpers.IsTestHostControllerSupported is
  true, without a `--crashdump` gate and without introducing a
  `--trx-mode` option or in-process opt-out.
- Replace the direct `--crashdump` check in TrxModeHelpers with actual
  controller-presence state: TrxModeHelpers.ShouldUseOutOfProcessTrxGeneration
  now checks PlatformCommandLineProvider.TestHostControllerPIDOptionKey in
  the child test host, instead of assuming which extension caused
  isolation.
- Keep the existing in-process implementation as the automatic
  compatibility fallback on browser, iOS, tvOS, and WASI, where process
  restart is unavailable.
- Update TRX artifact-heading expectations ("In process" -> "Out of
  process") in TrxTests.cs and TrxDataRowTests.cs to reflect the new
  default, drop the now-unnecessary `--crashdump` flag from crash/timeout
  acceptance tests, and add explicit coverage
  (Trx_WhenOnlyReportTrxIsSpecified_UsesControllerBackedRecoveryByDefault)
  proving plain `--report-trx` is controller-backed on supported
  platforms.
- Add TrxModeHelpersTests covering actual controller-presence handling.

Depends on #10797 (prerequisite timeout-lifecycle work), currently at
d521a2c; this branch is based on main and does not include its
timeout changes.

Fixes #10792

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings August 27, 2026 15:03

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

Defaults TRX reporting to controller-backed recovery on supported platforms while retaining in-process fallback elsewhere.

Changes:

  • Detects controller support and child-process controller presence.
  • Enables controller-backed TRX registration by default.
  • Updates unit, crash-recovery, and artifact-output tests.
Show a summary per file
File Description
TrxProcessLifetimeHandlerTests.cs Removes the crash-dump prerequisite.
TrxModeHelpersTests.cs Tests controller-presence detection.
TrxTests.cs Verifies default controller-backed reporting and recovery.
TrxDataRowTests.cs Updates artifact-heading expectations.
TrxTestApplicationLifecycleCallbacks.cs Uses controller-presence logic.
TrxReportExtensions.cs Conditionally registers controller components.
TrxProcessLifetimeHandler.cs Enables default controller recovery.
TrxModeHelpers.cs Defines platform and controller detection.
TrxEnvironmentVariableProvider.cs Enables controller pipe configuration.
TrxDataConsumer.cs Updates TRX mode diagnostics.
InternalAPI.Unshipped.txt Tracks the new internal API.

Review details

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (1)

src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxModeHelpers.cs:31

  • There is still no recovery acceptance test for the HangDump combination called out by #10792. The helper unit test supplies the controller PID directly, so it cannot detect registration/lifecycle conflicts when HangDump is what isolates and terminates the child. Add a --hangdump --report-trx termination test that verifies the recovered TRX, failed ResultSummary, and abnormal-run diagnostic.
    // Used from within the test host (child) process: rely on the controller-presence state that MTP
    // actually established for this process, rather than recomputing which extension requested
    // isolation. This stays true even when another extension (HangDump, --timeout, ...) is the one
    // that caused the controller to be used.
  • Files reviewed: 11/11 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxModeHelpers.cs Outdated
- Add RawPlatform_TrxReport_FallsBackInProcessUnderWasi acceptance test
  (WasmExecutionTests.cs) asserting plain --report-trx on wasi-wasm
  reports its artifact "In process" (never "Out of process"), directly
  proving TRX falls back automatically instead of attempting
  controller-backed recovery on a platform that cannot launch a
  test-host process.
- Extend WasmRuntime.RunUnderWasmtimeAsync with an optional arguments
  parameter so wasmtime invocations can pass extra MTP command-line
  options.
- Document the controller-backed-by-default behavior and its
  reliability/startup-cost tradeoff in TrxReport's PACKAGE.md, per
  issue #10792 acceptance criterion 6, including measured startup
  overhead for a trivial run: no statistically significant difference
  on .NET, roughly 700-800ms on .NET Framework.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 27, 2026 15:50

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.

Review details

  • Files reviewed: 14/14 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

One or more custom setup steps configured for this repository failed during this Copilot code review run:

Build the repository

Setup steps run before each review. If the review above is missing context, or no review was posted at all, the failing step above may be the cause. See the workflow run for failure details, fix your setup steps configuration, and re-request a review.

Note

You can configure setup steps for Copilot code review separately from Copilot cloud agent with a copilot-code-review.yml file. Read the docs for details.

main (via #10798 "Improve unknown command-line option guidance", merged
before this branch's main sync) added two new PlatformResources.resx
entries without a corresponding OneLocBuild pass, which fails CI's
`--report-trx`-unrelated Build Linux/Windows checks with an "xlf is
out-of-date" error from Microsoft.DotNet.XliffTasks. Regenerated via
`dotnet msbuild src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj /t:UpdateXlf`
per this repo's localization guidelines; no manual xlf edits.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 27, 2026 16:03

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.

Review details

  • Files reviewed: 27/27 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxModeHelpers.cs Outdated
TrxModeHelpers.IsTestHostControllerSupported hardcoded `true` for every
non-NETCOREAPP build, but this assembly also ships a netstandard2.0
asset that is explicitly marked as supporting browser/iOS/tvOS/WASI.
Consumers selecting that asset would register the named-pipe/process
controller path unconditionally instead of the promised in-process
fallback, and browser controller registration can throw.

Restore the `Polyfills` import and evaluate all four
OperatingSystem.Is*() checks unconditionally: under NETCOREAPP they
resolve via the BCL, and under netstandard2.0/.NET Framework they
resolve via the Polyfills OperatingSystem extension, which already
returns constant false for these platforms on .NET Framework (which
cannot run on them) while evaluating the actual runtime via
RuntimeInformation.IsOSPlatform for netstandard2.0 hosts that can
(e.g. Mono/MAUI).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 27, 2026 16:21

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.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Platform/Microsoft.Testing.Extensions.TrxReport/PACKAGE.md:25

  • A hang by itself does not trigger recovery: the controller finalizes TRX only after the child exits. Please avoid implying that plain --report-trx recovers a still-running hung host; name the terminating mechanism, such as HangDump, instead.
On platforms that can launch a test-host process (all except browser, iOS, tvOS, and WASI), TRX uses controller-backed recovery by default: the test host still streams results and generates the report during normal execution, but a surviving controller process can recover completed results into a TRX report if the test host crashes, hangs, or is stopped by `--timeout`. Browser, iOS, tvOS, and WASI cannot launch a test-host process, so TRX automatically falls back to its original in-process implementation there — no controller-backed recovery is attempted, and no configuration is required to get this fallback.
  • Files reviewed: 27/27 changed files
  • Comments generated: 1
  • Review effort level: Balanced

@github-actions github-actions Bot 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.

Note

🤖 Automated review by GitHub Copilot. Generated by the Expert Code Review workflow. To request a follow-up action, reply by tagging @copilot directly.

✅ 22/22 dimensions clean — no findings.

Summary of changes reviewed:

  • TRX report generation is now controller-backed by default on platforms that support it (decoupled from --crashdump).
  • Platform guards extended from browser-only to browser + iOS + tvOS + WASI, with correct [UnsupportedOSPlatform]/[UnsupportedOSPlatformGuard] annotations and lowercase platform names.
  • ShouldUseOutOfProcessTrxGeneration now checks TestHostControllerPIDOptionKey (actual controller presence) instead of CrashDumpOptionName, correctly decoupling the child-process detection from any specific extension.
  • IsTestHostControllerSupported is a static cached property — no per-call overhead, thread-safe by construction.
  • New unit tests (TrxModeHelpersTests), updated integration tests, and a new WASI acceptance test (RawPlatform_TrxReport_FallsBackInProcessUnderWasi) all verify the behavioral change.
  • XLF files contain regenerated entries for CommandLineOptionRequiresExtension and CommandLineOptionSuggestion (resx already present on the branch).
  • PACKAGE.md updated with clear documentation of the controller-backed default and its performance characteristics.
  • Internal API surface declared in InternalAPI.Unshipped.txt.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10808

GradeTestMutationNotesHow to improve
B (80–89) new TrxTests.
Trx_
WhenOnlyReportTrxIsSpecified_
UsesControllerBackedRecoveryByDefault
1/2 killed Only checks the console heading; a mutation that prints the heading but skips writing the TRX file survives. Assert a TRX file actually exists (as sibling tests do).
B (80–89) mod TrxTests.
Trx_
WhenTestHostCrash_
ErrorIsDisplayedInsideTheTrx
N/A Correctly drops --crashdump to prove controller-backed recovery is now the default; assertions unchanged and still meaningful. —
B (80–89) mod TrxTests.
Trx_
WhenTestHostCrash_
RunningUnderDotnetTest_
ErrorIsDisplayedInsideTheTrx
N/A Same intent as the sibling raw-host test; correctly exercises the dotnet test path without --crashdump. —
B (80–89) mod TrxTests.
Trx_
WhenOutOfProcessReportHasNoSelectedTests_
LifetimeHandshakeCompletes
N/A Only the redundant --crashdump flag was removed; the underlying zero-tests handshake assertion is unaffected and still solid. —
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
IsFalse_
WhenTestHostControllerPidOptionIsNotSet
2/2 killed Directly pins the false branch when the controller PID option is absent, killing the obvious short-circuit mutation. —
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
ReflectsControllerSupport_
WhenTestHostControllerPidOptionIsSet
2/2 killed Compares against the live IsTestHostControllerSupported value, so it stays correct and still catches platform-check mutations. —
A (90–100) new WasmExecutionTests.
RawPlatform_
TrxReport_
FallsBackInProcessUnderWasi
3/3 killed Asserts the positive ("In process"), negative ("Out of process" absent), and count/exit-code facets of the wasi TRX fallback contract. —
A (90–100) mod TrxProcessLifetimeHandlerTests.
BeforeTestHostProcessStartAsync_
CreatesPipeBeforeSchedulingConnectionWait
N/A Only a stale CrashDump command-line entry was removed from the test's setup dictionary; pipe-creation ordering assertions are untouched. —

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 173.7 AIC · ⌖ 1.18 AIC · ⊞ 16.9K · [◷]( · ◷)

@github-actions github-actions Bot 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.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 173.7 AIC · ⌖ 1.18 AIC · ⊞ 16.9K · ◷

Trx_WhenOnlyReportTrxIsSpecified_UsesControllerBackedRecoveryByDefault
only asserted the console heading text, which would still pass even if
a regression printed the right heading but skipped writing the TRX
file. Give the run an explicit --report-trx-filename and assert the
file exists, matching the sibling tests in this file.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 28, 2026 11:31
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10808

GradeTestMutationNotesHow to improve
C (70–79) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
ReflectsControllerSupport_
WhenTestHostControllerPidOptionIsSet
2/3 killed Expected value is the same production property being exercised, so it's self-referential on this always-true CI host. Assert a fixed true instead of comparing to IsTestHostControllerSupported.
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
IsFalse_
WhenTestHostControllerPidOptionIsNotSet
3/3 killed Asserts a fixed expected value (false) independent of the property under test — a real oracle. —
A (90–100) new TrxTests.
Trx_
WhenOnlyReportTrxIsSpecified_
UsesControllerBackedRecoveryByDefault
4/4 killed Checks the "Out of process" heading and confirms exactly one TRX file was produced via Directory.GetFiles. —
A (90–100) new WasmExecutionTests.
RawPlatform_
TrxReport_
FallsBackInProcessUnderWasi
5/5 killed Positively asserts "In process" and explicitly rules out "Out of process", plus checks TRX file count and exit code — covers the wasi fallback branch directly. —
A (90–100) mod TrxTests.
Trx_
WhenTestHostCrash_
ErrorIsDisplayedInsideTheTrx
N/A Only the launched command line changed (dropped now-redundant --crashdump); assertions are unchanged and still meaningful. —
A (90–100) mod TrxTests.
Trx_
WhenTestHostCrash_
RunningUnderDotnetTest_
ErrorIsDisplayedInsideTheTrx
N/A Same minimal change as the sibling test above; still asserts the crash is surfaced in the TRX. —
A (90–100) mod TrxTests.
Trx_
WhenOutOfProcessReportHasNoSelectedTests_
LifetimeHandshakeCompletes
N/A Dropping --crashdump correctly reflects that plain --report-trx is now controller-backed on its own. —

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 97.1 AIC · ⌖ 1.17 AIC · ⊞ 16.9K · [◷]( · ◷)

@github-actions github-actions Bot 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.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 97.1 AIC · ⌖ 1.17 AIC · ⊞ 16.9K · ◷

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 review overview

Review tier: Balanced
Findings: 1 High severity

New issues introduced by this change (1)
Severity Finding
High severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — Android is also a supported target for this package (`Microsoft.Testing.Extensions.TrxReport.csproj:…
Issues resolved since last review (1)
Severity Finding
High severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxReportExtensions.cs — This unconditional controller registration breaks --report-trx for sandboxed… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Platform/Microsoft.Testing.Extensions.TrxReport/PACKAGE.md:25

  • This supported-platform list incorrectly includes Android among controller-capable platforms. The package targets Android, but Android cannot launch the child test-host process used by controller-backed mode; document Android as an in-process fallback alongside the other sandboxed targets once the predicate is corrected.
On platforms that can launch a test-host process (all except browser, iOS, tvOS, and WASI), TRX uses controller-backed recovery by default: the test host still streams results and generates the report during normal execution, but a surviving controller process can recover completed results into a TRX report if the test host crashes, hangs, or is stopped by `--timeout`. Browser, iOS, tvOS, and WASI cannot launch a test-host process, so TRX automatically falls back to its original in-process implementation there — no controller-backed recovery is attempted, and no configuration is required to get this fallback.

ShouldUseOutOfProcessTrxGeneration_ReflectsControllerSupport_WhenTestHostControllerPidOptionIsSet
compared its result against TrxModeHelpers.IsTestHostControllerSupported
itself, which is tautological on every CI host this project targets
(net462/net472/net8.0/net9.0, none of which are
browser/ios/tvos/wasi): the assertion would still pass even if both
sides broke identically. Assert the fixed expected value (true)
instead, since this test always runs on a supported platform.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 28, 2026 11:46
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10808

GradeTestMutationNotesHow to improve
C (70–79) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
ReflectsControllerSupport_
WhenTestHostControllerPidOptionIsSet
1/2 killed Hardcoded true is right, but IsTestHostControllerSupported is always true on any CI host able to run this test, so an AND→OR mutation of the production predicate can't be observed. Already flagged inline in an earlier pass (unresolved); no new action needed here.
A (90–99) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
IsFalse_
WhenTestHostControllerPidOptionIsNotSet
2/2 killed Fixed expected value, exercises the missing-PID branch directly. —
A (90–99) new TrxTests.
Trx_
WhenOnlyReportTrxIsSpecified_
UsesControllerBackedRecoveryByDefault
3/3 killed Now asserts both the "Out of process" heading and that exactly one TRX file was produced (already fixed from an earlier review round). —
A (90–99) mod TrxTests.
Trx_
WhenOutOfProcessReportHasNoSelectedTests_
LifetimeHandshakeCompletes
N/A Only the --crashdump flag was dropped from the command line; assertions on exit code, summary counts, and TRX counters are unchanged and still effective. —
A (90–99) mod TrxTests.
Trx_
WhenTestHostCrash_
ErrorIsDisplayedInsideTheTrx
N/A Only the --crashdump flag was dropped; still asserts the crash message and Failed outcome inside the TRX. —
A (90–99) mod TrxTests.
Trx_
WhenTestHostCrash_
RunningUnderDotnetTest_
ErrorIsDisplayedInsideTheTrx
N/A Only the --crashdump flag was dropped from the dotnet test invocation; assertions unchanged. —
A (90–99) new WasmExecutionTests.
RawPlatform_
TrxReport_
FallsBackInProcessUnderWasi
4/4 killed Checks for absence of PlatformNotSupportedException, the pass/fail summary, the "In process" heading (and absence of "Out of process"), and the TRX file count — a thorough, well-targeted WASI regression guard. —
A (90–99) mod TrxProcessLifetimeHandlerTests.
BeforeTestHostProcessStartAsync_
CreatesPipeBeforeSchedulingConnectionWait
N/A Only the unused CrashDumpCommandLineOptions entry and import were removed; pipe-connection assertions are unaffected. —

Note: the private helper AssertTrxReportWasGeneratedAsync in TrxTests.cs / TrxDataRowTests.cs was also touched (updated expected heading text to "Out of process") but is not itself a test method, so it isn't graded. One prior review finding (self-referential-style assertion in ShouldUseOutOfProcessTrxGeneration_ReflectsControllerSupport_WhenTestHostControllerPidOptionIsSet) is already posted as an unresolved inline comment from an earlier run of this workflow and is intentionally not duplicated here.

This advisory comment was generated automatically. Grades are heuristic and informational — they do not block merging. Suggestions on the Files changed tab can be applied with one click. Re-run with /review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 100.4 AIC · ⌖ 1.17 AIC · ⊞ 16.9K · [◷]( · ◷)

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 review overview

Review tier: Balanced
Findings: 1 High severity · 1 Medium severity

New issues introduced by this change (1)
Severity Finding
Medium severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — The new PID-based decision is intended to fix the HangDump combination, but no acceptance test…
Pre-existing issues (1)
Severity Finding
High severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — Android is also a supported target for this package (`Microsoft.Testing.Extensions.TrxReport.csproj:… View comment

.NET Android cannot use the platform's default Process.Start-based
launch path (TestHostControllersTestHost.ProcessLifecycle) to spawn an
arbitrary child test host, even though this package targets android as
a supported platform (see the csproj's SupportedPlatform entries).
Before this fix, TrxModeHelpers.IsTestHostControllerSupported treated
Android as controller-capable, so making --report-trx controller-backed
by default (per #10792) would have regressed Android runs with a
process-launch failure: previously TRX was in-process everywhere by
default and only went out-of-process when --crashdump was explicitly
set, so Android was never exposed to this failure mode until now.

Add OperatingSystem.IsAndroid() to the same exclusion set already used
for browser/ios/tvos/wasi throughout TrxModeHelpers,
TrxProcessLifetimeHandler, TrxReportExtensions, and
TrxTestApplicationLifecycleCallbacks, and document the fallback in
PACKAGE.md.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 28, 2026 12:26
@github-actions

This comment has been minimized.

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 review overview

Review tier: Balanced
Findings: 1 Medium severity

Pre-existing issues (1)
Severity Finding
Medium severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — The new PID-based decision is intended to fix the HangDump combination, but no acceptance test… View comment
Issues resolved since last review (1)
Severity Finding
High severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — Android is also a supported target for this package (`Microsoft.Testing.Extensions.TrxReport.csproj:… View resolved comment

@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10808

GradeTestMutationNotesHow to improve
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
IsFalse_
WhenTestHostControllerPidOptionIsNotSet
2/2 killed Isolates the "no PID option" branch of the AND condition with an independent, fixed expected value. —
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
ReflectsControllerSupport_
WhenTestHostControllerPidOptionIsSet
2/2 killed Now asserts a fixed true instead of comparing to IsTestHostControllerSupported, fixing the earlier self-referential assertion. —
A (90–100) mod TrxProcessLifetimeHandlerTests.
BeforeTestHostProcessStartAsync_
CreatesPipeBeforeSchedulingConnectionWait
2/2 killed Change only drops an unused CrashDump option key; deferred-task and pipe-connection assertions remain intact. —
A (90–100) new TrxTests.
Trx_
WhenOnlyReportTrxIsSpecified_
UsesControllerBackedRecoveryByDefault
3/3 killed Now checks exit code, the "Out of process" heading, and an actual single TRX file on disk, closing the earlier heading-only gap. —
A (90–100) mod TrxTests.
Trx_
WhenOutOfProcessReportHasNoSelectedTests_
LifetimeHandshakeCompletes
4/4 killed Dropping the now-redundant --crashdump flag doesn't weaken any of the exit-code/timeout/summary/TRX-counter assertions. —
A (90–100) mod TrxTests.
Trx_
WhenTestHostCrash_
ErrorIsDisplayedInsideTheTrx
3/3 killed Still asserts exit code, crash message via regex, and Failed outcome after removing the now-implicit --crashdump flag. —
A (90–100) mod TrxTests.
Trx_
WhenTestHostCrash_
RunningUnderDotnetTest_
ErrorIsDisplayedInsideTheTrx
2/2 killed Same as the direct-host crash test but through dotnet test; assertions unaffected by the flag removal. —
A (90–100) new WasmExecutionTests.
RawPlatform_
TrxReport_
FallsBackInProcessUnderWasi
5/5 killed Directly proves the wasi in-process fallback via mutually-exclusive heading assertions, exception absence, file count, and run summary. —

All test-quality findings previously raised by earlier automated review passes on these files (missing TRX-file assertion on Trx_WhenOnlyReportTrxIsSpecified_UsesControllerBackedRecoveryByDefault, and the self-referential assertion in ShouldUseOutOfProcessTrxGeneration_ReflectsControllerSupport_WhenTestHostControllerPidOptionIsSet) have already been fixed by the author in later commits on this branch. No new high-confidence, actionable findings were identified in this pass, so no inline suggestions were posted.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 109.8 AIC · ⌖ 2.13 AIC · ⊞ 16.9K · [◷]( · ◷)

Address review feedback: the new PID-based controller-backed decision
in TrxModeHelpers is meant to make TRX recover correctly whenever a
controller is present for any reason (HangDump, --timeout, plain
--report-trx, ...), but no test exercised a HangDump termination
combined with TRX. ForwardCompatibilityTests runs
--hangdump --report-trx together, but only on a host that completes
normally, so it never reaches the controller's crash-recovery path.

Add HangDumpPlusTrxTests: a dedicated asset simulates a real hang (one
test completes and is streamed to the TRX sidecar, the next sleeps
well past --hangdump-timeout), asserts HangDump actually kills the
host, and verifies the recovered TRX has a failed ResultSummary and
contains the completed test but not the one that never finished.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 28, 2026 12:41
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Expert test review — PR #10808

GradeTestMutationNotesHow to improve
A (90–100) new HangDumpPlusTrxTests.
HangDumpPlusTrx_
WhenTestHostHangs_
RecoversCompletedResultsAndFailedResultSummary
4/4 killed Asserts dump count, single trx file, failed ResultSummary, Test1 present, Test2 absent — covers the full recovery contract. —
A (90–100) new TrxTests.
Trx_
WhenOnlyReportTrxIsSpecified_
UsesControllerBackedRecoveryByDefault
3/3 killed Directly proves controller-backed default via the "Out of process" marker plus a single-trx-file check. —
A (90–100) new WasmExecutionTests.
RawPlatform_
TrxReport_
FallsBackInProcessUnderWasi
4/4 killed Verifies no PlatformNotSupportedException, run summary intact, "In process" (not "Out of process") marker, and single trx file under wasi. —
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
IsFalse_
WhenTestHostControllerPidOptionIsNotSet
1/1 killed Isolated unit test confirms the PID-option gate is required even when the platform supports controllers. —
A (90–100) new TrxModeHelpersTests.
ShouldUseOutOfProcessTrxGeneration_
ReflectsControllerSupport_
WhenTestHostControllerPidOptionIsSet
1/1 killed Asserts a fixed expected value rather than comparing to IsTestHostControllerSupported, avoiding a self-referential check. —

The other test-file edits in this PR (TrxDataRowTests.cs, TrxTests.cs existing-test tweaks, TrxProcessLifetimeHandlerTests.cs) only adjust assertion strings or remove a now-irrelevant --crashdump/CrashDumpCommandLineOptions reference inside existing test bodies or a shared private helper (AssertTrxReportWasGeneratedAsync) — no new or materially changed test methods to grade there.

This advisory comment was generated automatically. Grades are heuristic
and informational — they do not block merging. Suggestions on the Files
changed tab can be applied with one click. Re-run with
/review-tests.

🤖 Automated content by GitHub Copilot. Generated by the Test Reviewer on PR (on open / sync) workflow. · auto · 89.7 AIC · ⌖ 1.13 AIC · ⊞ 16.9K · [◷]( · ◷)

@github-actions

Copy link
Copy Markdown
Contributor

🧵 Parallel-safety audit — PR #10808

Parallelization — assemblies containing the changed test files:

Test assembly Scope Workers Analyzer coverage
Microsoft.Testing.Platform.Acceptance.IntegrationTests MethodLevel ([assembly: Parallelize] in Program.cs) 0 (CPU count) coverable once the parallel-safety analyzers ship (attribute-based opt-in)
Microsoft.Testing.Extensions.UnitTests MethodLevel ([assembly: Parallelize] in Program.cs) 0 (CPU count) coverable once the parallel-safety analyzers ship (attribute-based opt-in)
Microsoft.Testing.TestInfrastructure n/a (shared test utility library, not a test assembly) n/a n/a

Both audited assemblies opt into MethodLevel parallelism, so every method — same-class or cross-class — is a live concurrent chunk. I reviewed all seven changed .cs files (HangDumpPlusTrxTests.cs (new), TrxDataRowTests.cs, TrxTests.cs, WasmExecutionTests.cs, TrxModeHelpersTests.cs (new), TrxProcessLifetimeHandlerTests.cs, WasmRuntime.cs) against the taxonomy:

  • Category A (process-global state). No Environment.SetEnvironmentVariable, Directory.SetCurrentDirectory, CultureInfo.DefaultThreadCurrentCulture, Console.Set*, or mutable-static writes were added. HangDumpPlusTrxTests passes SLEEPTIMEMS1/SLEEPTIMEMS2 through testHost.ExecuteAsync(..., new Dictionary<string,string?>{...}), which sets env vars only for the spawned child test-host process, not the current (test) process — not a category-A mutation.
  • Category B (shared filesystem paths). Every new/changed test generates its own asset via TestAsset.GenerateAssetAsync/GetAssetsToGenerate() (unique per-test directories, the established pattern in this suite) and writes results under a Guid.NewGuid()-named subdirectory or filename (resultDirectory, fileName, TrxFileName). WasmRuntime.StageIcuData writes icudt.dat into the per-test appBundle directory, which is itself unique per generated asset — no cross-test convergence. No hardcoded shared absolute/relative paths were introduced.
  • Category C (declaration reconciliation). No [ResourceLock] or [DoNotParallelize] was added, removed, or left mismatched in the changed files; nothing here declares or should declare either.
  • Category D (over-serialization). No new/changed [DoNotParallelize] or overly-broad [ResourceLock] in scope.
  • Parallelization-state changes. The [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] attributes in both Program.cs files are pre-existing and unchanged by this PR — the PR only adds/edits test methods and a WasmRuntime helper's optional parameter, not any assembly-level config.

Findings: A 0 · B 0 · C 0 · D 0 — by severity: Critical 0 · High 0 · Warning 0 · Info 0.

Nothing in this PR introduces a parallel-safety hazard. Each new/changed test relies on the existing per-test asset-generation and GUID-named artifact pattern, which is already safe under MethodLevel parallelism.

Advisory only — heuristic, non-blocking. Re-run with /parallel-audit. This audit answers "is it parallel-safe?"; for testability, smells, or flakiness see the detect-static-dependencies / test-smell-detection / test-anti-patterns analyses.

🤖 Automated content by GitHub Copilot. Generated by the Parallel-safety audit on PR (on open / sync) workflow. · auto · 112.6 AIC · ⌖ 0.864 AIC · ⊞ 24.8K · [◷]( · ◷)

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 review overview

Review tier: Balanced
Findings: None

Issues resolved since last review (1)
Severity Finding
Medium severity src/​Platform/​Microsoft.Testing.Extensions.TrxReport/​TrxModeHelpers.cs — The new PID-based decision is intended to fix the HangDump combination, but no acceptance test… View resolved comment

@Evangelink
Amaury Levé (Evangelink) merged commit 537d6e6 into main Aug 28, 2026
39 checks passed
@Evangelink
Amaury Levé (Evangelink) deleted the dev/amauryleve/trx-controller-recovery branch August 28, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

state/needs-review Awaiting review from the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use controller-backed TRX recovery by default

3 participants