Skip to content

Share full dotnet test IPC serializer stack as source (ids 0-12)#9544

Open
Evangelink wants to merge 1 commit into
mainfrom
dev/amauryleve/share-dotnet-test-ipc-stack
Open

Share full dotnet test IPC serializer stack as source (ids 0-12)#9544
Evangelink wants to merge 1 commit into
mainfrom
dev/amauryleve/share-dotnet-test-ipc-stack

Conversation

@Evangelink

@Evangelink Evangelink commented Jul 1, 2026

Copy link
Copy Markdown
Member

Summary

Moves the entire dotnet test <-> Microsoft.Testing.Platform named-pipe IPC serializer stack (serializer ids 0-12) into the shared source package Microsoft.Testing.Platform.Internal.DotnetTest, so dotnet/sdk can consume a single source of truth instead of hand-copying the models/serializers.

Supports dotnet/sdk#51615. Today the SDK hand-maintains its own copies and only registers ids 0-10, so ids 11 (AzureDevOpsLogMessage, protocol 1.2.0) and 12 (DisplayMessage, protocol 1.3.0) arrive at the SDK, hit its UnknownMessage fallback, and are silently dropped. Sharing the full stack lets the SDK follow-up delete its copies and register/route 11 & 12.

No wire changes: serializer ids, field ids, field order and byte layout are untouched.

What changed

  • Shared the full stack via @(DotnetTestProtocolContractSource) in DotnetTestProtocolContract.props: the message models + serializers (ids 0-12), the serializer registry (RegisterSerializers), INamedPipeSerializer/IRequest/IResponse, BaseSerializer, NamedPipeSerializer<T>, and the registry-only NamedPipeBase.
  • Decoupled BaseSerializer from platform internals so it compiles standalone in a consumer with no reference to Microsoft.Testing.Platform: ApplicationStateGuard.Unreachable() -> a self-contained Unreachable(); RoslynDebug.Assert -> a self-contained [Conditional("DEBUG")] DebugAssert. Kept [Embedded] and the #if NETCOREAPP/netfx fork.
  • Split NamedPipeBase: the serializer registry stays in NamedPipeBase (shared); the framing/transport (WriteMessageAsync/ReadNextMessageAsync/buffers) moved verbatim into a new repo-local NamedPipeConnectionBase, from which NamedPipeServer/NamedPipeClient now derive. The transport is intentionally NOT shared (it differs per repo).
  • Introduced TraitMessage(string Key, string Value) as the platform-decoupled wire trait type, replacing the public TestMetadataProperty in DiscoveredTestMessage + its serializer. The host converts TestMetadataProperty -> TraitMessage at the boundary in DotnetTestDataConsumer. Same wire bytes (TraitMessageFieldsId.Key/.Value).
  • Updated the DotnetTestProtocolContract.props header comment and PACKAGE.md to describe the now-shared full stack.

Tests

  • The standalone Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests project imports the shared .props and compiles the whole stack with no reference to Microsoft.Testing.Platform (proving standalone/SDK consumability). Added round-trip serialize/deserialize coverage including ids 11 & 12 and a DiscoveredTest with traits. Builds net9.0/net8.0/net462 (0/0) and passes 21/21.
  • In-repo Microsoft.Testing.Platform.UnitTests IPC round-trip + DotnetTestDataConsumer tests continue to pass against the refactored types.

Behavioral note

The DiscoveredTest trait decode path now throws InvalidOperationException (was UnreachableException via ApplicationStateGuard) on malformed input — clearer message, reachable only on corrupt wire data, no wire/format change.

Follow-up (separate, in dotnet/sdk)

Once this package flows via darc: delete the SDK's Microsoft.DotNet.Cli.Commands.Test.IPC.* copies, re-point to Microsoft.Testing.Platform.IPC.*, register the ids 11/12 serializers, and route AzureDevOpsLogMessage/DisplayMessage to the TerminalTestReporter sinks.

Copilot AI review requested due to automatic review settings July 1, 2026 14:43
@Evangelink Evangelink force-pushed the dev/amauryleve/share-dotnet-test-ipc-stack branch from 3d1a417 to 5e29be6 Compare July 1, 2026 14:46

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 consolidates the full dotnet test ↔ Microsoft.Testing.Platform named-pipe IPC protocol serializer stack (serializer ids 0–12) into the shared-source contract so dotnet/sdk can consume a single canonical implementation, including ids 11/12, without hand-copied drift.

Changes:

  • Expanded the shared protocol contract manifest to include models, serializers, registry, and base serializer infrastructure (ids 0–12) while keeping transport/framing repo-local.
  • Decoupled shared serializer code from platform internals (e.g., RoslynDebug, ApplicationStateGuard) and introduced TraitMessage as the protocol’s trait wire type.
  • Added standalone unit tests to compile and round-trip the shared protocol stack without referencing Microsoft.Testing.Platform.
Show a summary per file
File Description
test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests.csproj Compiles all polyfills to validate standalone/shared-source consumption across TFMs.
test/UnitTests/Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTests/DotnetTestProtocolSerializerTests.cs New round-trip and registry coverage for serializers 0–12 (including 11/12).
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestSessionEventSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestResultMessagesSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestInProgressMessagesSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/FileArtifactMessagesSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/DisplayMessageSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/DiscoveredTestMessagesSerializer.cs Moves traits to TraitMessage and removes platform-coupled dependencies from the shared serializer.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/CommandLineOptionMessagesSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/AzureDevOpsLogMessageSerializer.cs Switches to shared DebugAssert helper for serializer invariants.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/DiscoveredTestMessages.cs Introduces TraitMessage as the protocol wire trait type and updates discovered-test models accordingly.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs Converts platform TestMetadataProperty traits into protocol TraitMessage at the boundary.
src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestProtocolContract.props Expands shared contract file list to the full serializer stack and documents the new scope/constraints.
src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs Adds self-contained DebugAssert/Unreachable helpers to remove platform-internal dependencies from shared source.
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs Moves to the new transport base (NamedPipeConnectionBase) to keep NamedPipeBase registry-only for sharing.
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeConnectionBase.cs New: repo-local framing/transport implementation split out from the shareable registry base.
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs Moves to the new transport base (NamedPipeConnectionBase) to keep NamedPipeBase registry-only for sharing.
src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs Refactored to be a serializer registry only (shareable with dotnet/sdk).
src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/PACKAGE.md Updates package documentation to describe the newly shared full protocol stack.

Review details

  • Files reviewed: 22/22 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment thread src/Platform/Microsoft.Testing.Platform.Internal.DotnetTest/PACKAGE.md Outdated
Comment thread src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs Outdated
Copilot AI review requested due to automatic review settings July 1, 2026 14:48

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: 22/22 changed files
  • Comments generated: 0 new
  • Review effort level: Low

@Evangelink Evangelink force-pushed the dev/amauryleve/share-dotnet-test-ipc-stack branch from 5e29be6 to a4583f7 Compare July 1, 2026 15:08
@Evangelink Evangelink marked this pull request as ready for review July 1, 2026 15:14
Copilot AI review requested due to automatic review settings July 1, 2026 15:14
@Evangelink Evangelink force-pushed the dev/amauryleve/share-dotnet-test-ipc-stack branch from a4583f7 to 6b93b52 Compare July 1, 2026 15: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

  • Files reviewed: 22/22 changed files
  • Comments generated: 3
  • Review effort level: Low

Comment on lines +151 to +153
int currentMessageSize = BitConverter.ToInt32(_readBuffer, 0);
int missingBytesToReadOfWholeMessage = currentMessageSize;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks — this is a fair robustness point, but ReadNextMessageAsync here is pre-existing transport code moved verbatim out of NamedPipeBase into the new repo-local NamedPipeConnectionBase (it is intentionally NOT part of the shared serializer stack). This PR is a wire-neutral source-share refactor and deliberately keeps the transport behavior byte-for-byte identical, so I would prefer not to change the frame-size handling here. Happy to track header-size validation as a separate hardening follow-up. Leaving this thread open for your call.

Copilot AI review requested due to automatic review settings July 1, 2026 15:21
Move the entire `dotnet test` named-pipe serializer stack (message models +
serializers for ids 0-12, the serializer registry and base infrastructure)
into @(DotnetTestProtocolContractSource) so it ships as contentFiles in the
Microsoft.Testing.Platform.Internal.DotnetTest source package. This gives
dotnet/sdk a single source of truth and fixes the silent drop of ids 11
(AzureDevOpsLogMessage) and 12 (DisplayMessage), which the SDK never
registered (see dotnet/sdk#51615).

Decoupling (no wire change - ids, field ids, order and byte layout unchanged):
- BaseSerializer: self-contained Unreachable()/DebugAssert helpers instead of
  ApplicationStateGuard/RoslynDebug, so it compiles standalone.
- NamedPipeBase split: registry-only base is shared; framing/buffers moved to
  a new repo-local NamedPipeConnectionBase (NamedPipeServer/Client re-parented).
- DiscoveredTestMessage uses a shared, platform-decoupled TraitMessage(Key,Value)
  wire type instead of the public TestMetadataProperty; the host converts at the
  boundary in DotnetTestDataConsumer.

Extend the standalone DotnetTestProtocolContract.UnitTests with round-trip
coverage (incl. ids 11/12 and traits) proving the stack compiles/serializes with
no reference to Microsoft.Testing.Platform. Update PACKAGE.md and the .props docs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink force-pushed the dev/amauryleve/share-dotnet-test-ipc-stack branch from 6b93b52 to 18cbd8a Compare July 1, 2026 15:24

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: 22/22 changed files
  • Comments generated: 0 new
  • Review effort level: Low

Copilot AI review requested due to automatic review settings July 1, 2026 15:25

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: 22/22 changed files
  • Comments generated: 1
  • Review effort level: Low

Comment on lines +33 to +35
// Exposes the protected registry lookup so the test can assert every id 0-12 is registered.
// Exposes the protected registry lookups so the test can assert both the id-based mapping (every id 0-12 is
// registered) and the type-based mapping (GetSerializer(Type), used by the runtime serialize path).
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