Skip to content

Forward Azure DevOps log commands and host display messages to dotnet test (protocol 1.2.0/1.3.0)#55221

Merged
Evangelink merged 3 commits into
mainfrom
dev/amauryleve/azdo-log-forwarding-dotnet-test
Jul 10, 2026
Merged

Forward Azure DevOps log commands and host display messages to dotnet test (protocol 1.2.0/1.3.0)#55221
Evangelink merged 3 commits into
mainfrom
dev/amauryleve/azdo-log-forwarding-dotnet-test

Conversation

@Evangelink

Copy link
Copy Markdown
Member

Summary

Implements the consumer (SDK) side of the dotnet test (Microsoft.Testing.Platform pipe protocol) feature that lets Azure DevOps log grouping — and other forwarded host messages — reach the pipeline log. The host half already shipped in microsoft/testfx; this is the previously-missing dotnet/sdk half.

Under dotnet test with MTP, the test host runs as a child process and talks to the SDK over a named pipe. The host installs a forwarding output device that forwards two message classes over the pipe, gated on the negotiated protocol version:

  • AzureDevOpsLogMessage (serializer id 11, protocol 1.2.0+) — verbatim Azure DevOps logging commands (##[group] / ##[endgroup] / ##vso[...]) produced by the AzureDevOpsReport extension. Must be written verbatim so AzDO renders the collapsible group.
  • DisplayMessage (serializer id 12, protocol 1.3.0+) — generic host warning/error/info diagnostics produced outside test results (hang/crash dump, retry summaries, generic extension/framework warnings+errors).

The SDK previously advertised only 1.0.0;1.1.0, so the host silently swallowed all of it. That was the core blocker.

Changes

  • CliConstants.cs: ProtocolConstants.SupportedVersions bumped 1.0.0;1.1.01.0.0;1.1.0;1.2.0;1.3.0. Added DisplayMessageLevels (Information=0, Warning=1, Error=2). 1.4.0 (reverse server-control pipe / server-initiated cancellation) is intentionally not advertised — separate, larger feature, out of scope (noted in a comment).
  • ObjectFieldIds.cs (vendored from testfx): added the id-11 (AzureDevOpsLogMessageFieldsId) and id-12 (DisplayMessageFieldsId) field classes. Ids 13/14 (server control, 1.4.0) intentionally omitted. The vendored baseline blob SHA in eng/vendored-files.json already matches upstream HEAD, so no manifest bump is needed.
  • Models (IPC/Models/): AzureDevOpsLogMessage(ExecutionId, InstanceId, LogText) and DisplayMessage(ExecutionId, InstanceId, byte Level, Text).
  • Serializers (IPC/Serializers/): AzureDevOpsLogMessageSerializer and DisplayMessageSerializer, mirroring the SDK's BaseSerializer + INamedPipeSerializer style. Wire layout matches testfx byte-for-byte (Level always written as a single byte; deserialize honors fieldSize so a future widening won't misalign). Both registered in RegisterSerializers.cs.
  • Dispatch (TestApplication.cs): route id 11 → OnAzureDevOpsLogReceived, id 12 → OnDisplayMessageReceived.
  • TestApplicationHandler.cs: verbatim write of LogText for AzDO; Level-mapped write for display messages (0→message, 1→warning, 2→error). Lenient — these are informational, not tied to a session, so they don't require the TestHost handshake and don't fail the run on missing content. Added matching trace-logging helpers.
  • TerminalTestReporter.cs: added WriteWarningMessage (DarkYellow) and WriteErrorMessage (DarkRed) sinks — the reporter previously only had a plain WriteMessage, so there was no clean warning/error sink for the display-message path.
  • Tests: serializer round-trip tests for both new serializers (populated fields, null-field omission, always-present Level byte, serializer-id contract).

Verification

  • Production CLI (src/Cli/dotnet/dotnet.csproj) builds clean: 0 warnings, 0 errors.
  • New serializer round-trip tests pass (--filter FullyQualifiedName~SerializerTests): 15/15 passed, 0 failed, covering ExecutionId/InstanceId/LogText and ExecutionId/InstanceId/Level/Text preservation including null-field omission and the always-present Level byte.

Notes

  • ObjectFieldIds.cs is vendored from testfx (src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs) and tracked in eng/vendored-files.json.
  • Left as draft per request.

… test (protocol 1.2.0/1.3.0)

The Microsoft.Testing.Platform host forwards AzureDevOpsLogMessage (serializer id 11, protocol 1.2.0+) and DisplayMessage (serializer id 12, protocol 1.3.0+) over the dotnet-test named pipe, gated on the negotiated protocol version. The SDK only advertised 1.0.0;1.1.0, so the host silently swallowed all of it.

This adds the consumer side: bump SupportedVersions to 1.0.0;1.1.0;1.2.0;1.3.0, add the id-11/id-12 field classes (vendored from testfx), the two model records and serializers, register + dispatch them, and handle them in TestApplicationHandler (verbatim AzDO log text; Level-mapped display messages). Adds a WriteWarningMessage/WriteErrorMessage sink to TerminalTestReporter and serializer round-trip tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink marked this pull request as ready for review July 9, 2026 19:52
@Evangelink Evangelink requested a review from a team as a code owner July 9, 2026 19:52
Copilot AI review requested due to automatic review settings July 9, 2026 19:52

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

This PR updates the .NET SDK-side dotnet test Microsoft.Testing.Platform (MTP) named-pipe protocol support to negotiate newer protocol versions and forward new host-originated message types (Azure DevOps log commands and generic display diagnostics) to the CLI output, enabling Azure DevOps log grouping and better host diagnostics visibility.

Changes:

  • Advertise MTP protocol versions 1.2.0 and 1.3.0 (while explicitly not advertising 1.4.0).
  • Add IPC models + serializers for AzureDevOpsLogMessage (id 11) and DisplayMessage (id 12), register them, and dispatch them through TestApplicationTestApplicationHandler.
  • Extend terminal reporting to support warning/error display message sinks and add serializer round-trip tests for the new message types.
Show a summary per file
File Description
test/dotnet.Tests/CommandTests/Test/DisplayMessageSerializerTests.cs Adds round-trip and serializer-id contract tests for DisplayMessageSerializer.
test/dotnet.Tests/CommandTests/Test/AzureDevOpsLogMessageSerializerTests.cs Adds round-trip and serializer-id contract tests for AzureDevOpsLogMessageSerializer.
src/Cli/dotnet/Commands/Test/MTP/TestApplicationHandler.cs Handles forwarding of Azure DevOps log commands and generic display messages to terminal output.
src/Cli/dotnet/Commands/Test/MTP/TestApplication.cs Dispatches newly supported IPC request types to the handler.
src/Cli/dotnet/Commands/Test/MTP/Terminal/TerminalTestReporter.cs Adds warning/error output helpers for terminal reporting.
src/Cli/dotnet/Commands/Test/MTP/IPC/Serializers/RegisterSerializers.cs Registers the new serializers (ids 11 and 12).
src/Cli/dotnet/Commands/Test/MTP/IPC/Serializers/DisplayMessageSerializer.cs Implements wire-format serializer/deserializer for DisplayMessage.
src/Cli/dotnet/Commands/Test/MTP/IPC/Serializers/AzureDevOpsLogMessageSerializer.cs Implements wire-format serializer/deserializer for AzureDevOpsLogMessage.
src/Cli/dotnet/Commands/Test/MTP/IPC/ObjectFieldIds.cs Vendors field/serializer IDs for the new message types and documents omitted upstream ids.
src/Cli/dotnet/Commands/Test/MTP/IPC/Models/DisplayMessage.cs Adds IPC model for DisplayMessage.
src/Cli/dotnet/Commands/Test/MTP/IPC/Models/AzureDevOpsLogMessage.cs Adds IPC model for AzureDevOpsLogMessage.
src/Cli/dotnet/Commands/Test/CliConstants.cs Adds DisplayMessageLevels and expands supported protocol versions.

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 2

Comment thread src/Cli/dotnet/Commands/Test/MTP/TestApplicationHandler.cs
Comment thread src/Cli/dotnet/Commands/Test/MTP/TestApplicationHandler.cs
Copilot AI and others added 2 commits July 10, 2026 11:33
…nated

TerminalTestReporter.WriteMessage appends verbatim without a trailing newline (the process-output streaming path supplies its own newlines). Forwarded AzureDevOpsLogMessage / info-level DisplayMessage text arrives as line-based IPC payloads without a terminator, so an Azure DevOps logging command (e.g. ##[group]) or info line could concatenate with adjacent output. Terminate the line in the handler when missing, without altering the payload. Warning/error paths already use AppendLine.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink enabled auto-merge July 10, 2026 09:51
@Evangelink Evangelink merged commit 5b90b37 into main Jul 10, 2026
27 checks passed
@Evangelink Evangelink deleted the dev/amauryleve/azdo-log-forwarding-dotnet-test branch July 10, 2026 13:31
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.

4 participants