Share full dotnet test IPC serializer stack as source (ids 0-12)#9544
Share full dotnet test IPC serializer stack as source (ids 0-12)#9544Evangelink wants to merge 1 commit into
Conversation
3d1a417 to
5e29be6
Compare
There was a problem hiding this comment.
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 introducedTraitMessageas 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
5e29be6 to
a4583f7
Compare
a4583f7 to
6b93b52
Compare
| int currentMessageSize = BitConverter.ToInt32(_readBuffer, 0); | ||
| int missingBytesToReadOfWholeMessage = currentMessageSize; | ||
|
|
There was a problem hiding this comment.
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.
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>
6b93b52 to
18cbd8a
Compare
| // 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). |
Summary
Moves the entire
dotnet test<-> Microsoft.Testing.Platform named-pipe IPC serializer stack (serializer ids 0-12) into the shared source packageMicrosoft.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 itsUnknownMessagefallback, 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
@(DotnetTestProtocolContractSource)inDotnetTestProtocolContract.props: the message models + serializers (ids 0-12), the serializer registry (RegisterSerializers),INamedPipeSerializer/IRequest/IResponse,BaseSerializer,NamedPipeSerializer<T>, and the registry-onlyNamedPipeBase.BaseSerializerfrom platform internals so it compiles standalone in a consumer with no reference to Microsoft.Testing.Platform:ApplicationStateGuard.Unreachable()-> a self-containedUnreachable();RoslynDebug.Assert-> a self-contained[Conditional("DEBUG")]DebugAssert. Kept[Embedded]and the#if NETCOREAPP/netfx fork.NamedPipeBase: the serializer registry stays inNamedPipeBase(shared); the framing/transport (WriteMessageAsync/ReadNextMessageAsync/buffers) moved verbatim into a new repo-localNamedPipeConnectionBase, from whichNamedPipeServer/NamedPipeClientnow derive. The transport is intentionally NOT shared (it differs per repo).TraitMessage(string Key, string Value)as the platform-decoupled wire trait type, replacing the publicTestMetadataPropertyinDiscoveredTestMessage+ its serializer. The host convertsTestMetadataProperty -> TraitMessageat the boundary inDotnetTestDataConsumer. Same wire bytes (TraitMessageFieldsId.Key/.Value).DotnetTestProtocolContract.propsheader comment andPACKAGE.mdto describe the now-shared full stack.Tests
Microsoft.Testing.Platform.DotnetTestProtocolContract.UnitTestsproject imports the shared.propsand 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.Microsoft.Testing.Platform.UnitTestsIPC round-trip +DotnetTestDataConsumertests continue to pass against the refactored types.Behavioral note
The DiscoveredTest trait decode path now throws
InvalidOperationException(wasUnreachableExceptionviaApplicationStateGuard) 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 toMicrosoft.Testing.Platform.IPC.*, register the ids 11/12 serializers, and routeAzureDevOpsLogMessage/DisplayMessageto theTerminalTestReportersinks.