Add artifact post-processing orchestration#10086
Conversation
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
There was a problem hiding this comment.
Pull request overview
Implements RFC 018 artifact post-processing orchestration for MTP, including extension APIs, SDK handshake support, internal dispatching, and TRX merging.
Changes:
- Adds artifact post-processor contracts, registration, manifest routing, and pipe reporting.
- Promotes tool registration and adds the
merge-trxtool. - Adds API baselines, localized resources, and tests.
Show a summary per file
| File | Description |
|---|---|
test/UnitTests/Microsoft.Testing.Platform.UnitTests/Extensions/ArtifactPostProcessing/ArtifactPostProcessingTests.cs |
Tests capabilities, registration, and manifests. |
test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxArtifactPostProcessorTests.cs |
Tests TRX post-processing. |
test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoAllExtensionsTests.cs |
Adds merge-tool info expectations. |
src/Platform/Microsoft.Testing.Platform/Tools/IToolsManager.cs |
Makes tool registration public. |
src/Platform/Microsoft.Testing.Platform/Tools/ITool.cs |
Promotes and documents tool contracts. |
src/Platform/Microsoft.Testing.Platform/ServerMode/IPushOnlyProtocol.cs |
Adds identity and message sending. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs |
Adds handshake capabilities and modes. |
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs |
Advertises tool execution mode. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf |
Syncs Traditional Chinese resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf |
Syncs Simplified Chinese resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf |
Syncs Turkish resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf |
Syncs Russian resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf |
Syncs Portuguese resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf |
Syncs Polish resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf |
Syncs Korean resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf |
Syncs Japanese resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf |
Syncs Italian resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf |
Syncs French resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf |
Syncs Spanish resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf |
Syncs German resources. |
src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf |
Syncs Czech resources. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx |
Adds dispatcher diagnostics. |
src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.cs |
Exposes a resource to tests. |
src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt |
Tracks new public APIs. |
src/Platform/Microsoft.Testing.Platform/InternalAPI/InternalAPI.Unshipped.txt |
Tracks new internal APIs. |
src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs |
Adds pipe-aware tool execution. |
src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.Modes.cs |
Builds processors and dispatcher connections. |
src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs |
Registers built-in dispatcher components. |
src/Platform/Microsoft.Testing.Platform/Hosts/ITestHostBuilder.cs |
Adds processor registration internally. |
src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs |
Advertises processor capabilities. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/IArtifactPostProcessor.cs |
Defines processor contracts and DTOs. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/IArtifactPostProcessingManager.cs |
Defines processor registration. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingManifest.cs |
Parses orchestration manifests. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingManager.cs |
Builds registered processors. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingHandshakeProperties.cs |
Serializes processor capabilities. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingDispatcherTool.cs |
Routes and reports processed artifacts. |
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingDispatcherTool.CommandLine.cs |
Defines dispatcher CLI options. |
src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs |
Hides internal tools from info. |
src/Platform/Microsoft.Testing.Platform/Builder/TestApplicationBuilder.cs |
Exposes registration managers. |
src/Platform/Microsoft.Testing.Platform/Builder/ITestApplicationBuilder.cs |
Adds public registration surfaces. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportExtensions.cs |
Registers TRX processor and tool. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.Utilities.cs |
Generates deterministic merge IDs. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxMergeTool.cs |
Implements merge-trx. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxMergeTool.CommandLine.cs |
Defines merge-tool options. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs |
Marks the comparer visible. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxArtifactPostProcessor.cs |
Implements automatic TRX merging. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/ToolTrxMergeFactory.cs |
Creates merge-tool components. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.zh-Hant.xlf |
Syncs Traditional Chinese TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.zh-Hans.xlf |
Syncs Simplified Chinese TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.tr.xlf |
Syncs Turkish TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ru.xlf |
Syncs Russian TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.pt-BR.xlf |
Syncs Portuguese TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.pl.xlf |
Syncs Polish TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ko.xlf |
Syncs Korean TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.ja.xlf |
Syncs Japanese TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.it.xlf |
Syncs Italian TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.fr.xlf |
Syncs French TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.es.xlf |
Syncs Spanish TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.de.xlf |
Syncs German TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/xlf/ExtensionResources.cs.xlf |
Syncs Czech TRX resources. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/Resources/ExtensionResources.resx |
Adds TRX merge diagnostics. |
src/Platform/Microsoft.Testing.Extensions.TrxReport/InternalAPI/InternalAPI.Unshipped.txt |
Tracks TRX internal APIs. |
Review details
- Files reviewed: 62/62 changed files
- Comments generated: 4
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingManifest.cs:32
- This normalization is still incomplete on non-NETCOREAPP targets.
JsonConfigurationFileParser.netstandard.cs:34casts the deserialized root directly toJsonObject, so a valid non-object JSON root such as[]throwsInvalidCastException, notJsonException. That exception bypasses both this wrapper and the dispatcher'sIOException/UnauthorizedAccessException/FormatExceptionfilter, faulting the tool instead of returning the localized invalid-manifest result. NormalizeInvalidCastExceptionhere as well.
catch (JsonException ex)
{
throw new FormatException(ex.Message, ex);
}
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingManifest.cs:48
- An empty or scalar input entry is silently discarded instead of being rejected. The JSON parser represents
{}in the first array slot as the keyinputs:0, but thisparts.Length >= 3filter ignores that key, soinputs: [{}]loads as an empty manifest and never reaches the required-path check below. Include two-part index keys so every declared input is validated.
{
throw new FormatException(PlatformResources.ArtifactPostProcessingManifestInvalid);
}
int[] inputIndices = [.. values.Keys
.Where(key => key.StartsWith("inputs:", StringComparison.Ordinal))
.Select(key => key.Split(':'))
- Files reviewed: 63/63 changed files
- Comments generated: 1
- Review effort level: Medium
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
src/Platform/Microsoft.Testing.Platform/Tools/IToolsManager.cs:16
- The promoted registration surface is not usable for third-party tools that need arguments. Tool option scoping now requires
IToolCommandLineOptionsProvider(ToolsTestHost.cs:207-210), but that interface is internal (Tools/IToolCommandLineOptionsProvider.cs:8), so an external extension can register anIToolhere but cannot associate any command-line options with it; ordinary publicICommandLineOptionsProviderimplementations are rejected as unknown options. Expose a public way to bind option providers to a tool (for example, make the scoped provider contract public or add an options-aware registration overload).
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs:126 - The published dotnet-test pipe specification is now stale:
docs/mstest-runner-protocol/004-protocol-dotnet-test-pipe.md:337-345lists only the prior host types, execution modes, and properties through ID 13. DocumentArtifactPostProcessor,tool, and capability properties 14/15 so SDK and host implementers have an accurate wire contract.
- Files reviewed: 63/63 changed files
- Comments generated: 2
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingManifest.cs:101
- Malformed optional metadata is silently accepted. For example,
"kind": { "value": "trx" }has no scalar at thekindkey, so this first branch returnsnullbefore inspecting the raw JSON; empty objects/arrays follow the same path. This contradicts the manifest's string-or-null schema and the strict handling already applied to numeric metadata. Validate the raw JSON type whenever the property exists, then read its scalar value.
- Files reviewed: 75/75 changed files
- Comments generated: 0 new
- Review effort level: Medium
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
src/Platform/Microsoft.Testing.Platform/Extensions/ArtifactPostProcessing/ArtifactPostProcessingDispatcherTool.cs:138
- This path comparison is incorrect on case-insensitive non-Windows filesystems (notably default macOS volumes):
OrdinaltreatsInput.trxandinput.trxas different even when they resolve to the same file. It also compares lexical paths without resolving symlinks. Consequently, a processor output that aliases an input can pass this guard, violating the read-only-input contract, and a casing variant of the output directory can be rejected despite being valid. Please canonicalize paths (including links where supported) and determine case sensitivity for the output filesystem, asSharedExtensionHelpers/MergeOutputFileHelper.cs:17-42does.
StringComparison pathComparison = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? StringComparison.OrdinalIgnoreCase
: StringComparison.Ordinal;
return outputPath.StartsWith(outputDirectoryPrefix, pathComparison)
&& File.Exists(outputPath)
&& !inputs.Any(input => string.Equals(Path.GetFullPath(input.Path), outputPath, pathComparison))
- Files reviewed: 75/75 changed files
- Comments generated: 0 new
- Review effort level: Medium
This comment has been minimized.
This comment has been minimized.
🔍 Build Failure Analysis
What we know
What to doPlease inspect the originating [Azure DevOps build]((dev.azure.com/redacted) directly for the compiler errors, then check:
Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
This comment has been minimized.
This comment has been minimized.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 22566837-4117-4194-ba2a-94481459619d
🧪 Test quality grade — PR #1008632 tests graded across 7 files. 28 × A, 4 × C. The most common issue is a single
This advisory comment was generated automatically. Grades are heuristic Warning Firewall blocked 1 domainThe following domain was blocked by the firewall during workflow execution:
network:
allowed:
- defaults
- "awmgmcpg"See Network Configuration for more information.
|
Summary
Implements the remaining testfx-side pieces of RFC 018 so
dotnet/sdkcan orchestrate artifact consolidation after multi-module MTP runs.IArtifactPostProcessorcontract, DTOs, and registration surfaceinternal-merge-artifactsdispatcher with manifest routing and merged artifact return over the existing pipemerge-trxtool and TRX post-processor over the existing merge engineReview follow-ups
Two independent review passes were completed, including the MSTest/MTP expert reviewer. Follow-up fixes include:
Validation
Microsoft.Testing.Platform.UnitTests— 1399 passedMicrosoft.Testing.Extensions.UnitTests— 775 passed, 5 expected skipsmerge-trxend-to-end produced a valid merged TRX--helpand--infoacceptance tests passed across net462, net8.0, and net10.0Related to dotnet/sdk#47613 and RFC 018 (#9187).