diff --git a/Directory.Packages.props b/Directory.Packages.props
index 05ded62687..24b4919d5e 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -32,6 +32,7 @@
1.1.3-beta1.24423.1
+
@@ -43,7 +44,6 @@
-
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ActivityIndicatorMutexNameSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ActivityIndicatorMutexNameSerializer.cs
index c46d16b03c..1f521146f1 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ActivityIndicatorMutexNameSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ActivityIndicatorMutexNameSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ConsumerPipeNameSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ConsumerPipeNameSerializer.cs
index a2f5949803..c784ad2d4f 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ConsumerPipeNameSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ConsumerPipeNameSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ExitSignalActivityIndicatorTaskRequest.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ExitSignalActivityIndicatorTaskRequest.cs
index 72ab5a9bd0..90f2557e16 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ExitSignalActivityIndicatorTaskRequest.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/ExitSignalActivityIndicatorTaskRequest.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsRequest.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsRequest.cs
index 05cbf08b45..1e12d5a956 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsRequest.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsRequest.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsResponse.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsResponse.cs
index 04344f941c..293b6b8de5 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsResponse.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/GetInProgressTestsResponse.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/SessionEndSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/SessionEndSerializer.cs
index 8e547f6974..e03d57e85e 100644
--- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/SessionEndSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Serializers/SessionEndSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.HangDump.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs
index e3425beaaf..c8d6dec83f 100644
--- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.MSBuild.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs
index 062fd2d642..617c3e0617 100644
--- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.MSBuild.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs
index 4a612df01d..7f7809525c 100644
--- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.MSBuild.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
index 0cccbc5c94..bdaf383075 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj
@@ -49,6 +49,9 @@ This package extends Microsoft Testing Platform to provide a retry policy system
build/$(TargetFramework)
+
+
+
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs
index f47a8b2c19..154831bc9a 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs
index 1e8f38c1a2..5d4396e186 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs
index e959df04bc..e52ab56825 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs
index bfd5e8b4fb..38ce77e10b 100644
--- a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs
index 45832d23db..d543c72c2e 100644
--- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs
index b40b5f3ae8..58590cc55e 100644
--- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.IPC;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers;
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/INamedPipeSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/INamedPipeSerializer.cs
deleted file mode 100644
index 4788638ebe..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/IPC/INamedPipeSerializer.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.CodeAnalysis;
-
-namespace Microsoft.Testing.Platform.IPC;
-
-[Embedded]
-internal interface INamedPipeSerializer
-{
- int Id { get; }
-
- void Serialize(object objectToSerialize, Stream stream);
-
- object Deserialize(Stream stream);
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs
deleted file mode 100644
index da65b86576..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.CodeAnalysis;
-using Microsoft.Testing.Platform.Resources;
-
-namespace Microsoft.Testing.Platform.IPC;
-
-[Embedded]
-internal abstract class NamedPipeBase
-{
- private readonly Dictionary _typeSerializer = [];
- private readonly Dictionary _idSerializer = [];
-
- public void RegisterSerializer(INamedPipeSerializer namedPipeSerializer, Type type)
- {
- _typeSerializer.Add(type, namedPipeSerializer);
- _idSerializer.Add(namedPipeSerializer.Id, namedPipeSerializer);
- }
-
- protected INamedPipeSerializer GetSerializer(int id)
- => _idSerializer.TryGetValue(id, out INamedPipeSerializer? serializer)
- ? serializer
- : throw new ArgumentException(string.Format(
- CultureInfo.InvariantCulture,
- PlatformResources.NoSerializerRegisteredWithIdErrorMessage,
- id));
-
- protected INamedPipeSerializer GetSerializer(Type type)
- => _typeSerializer.TryGetValue(type, out INamedPipeSerializer? serializer)
- ? serializer
- : throw new ArgumentException(string.Format(
- CultureInfo.InvariantCulture,
- PlatformResources.NoSerializerRegisteredWithTypeErrorMessage,
- type));
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs
index 6d5b0caca8..bc7604e82c 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs
@@ -7,6 +7,8 @@
using System.IO.Pipes;
+using EasyNamedPipes;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.Helpers;
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
index 3cd3559467..bd9987356f 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs
@@ -3,6 +3,8 @@
using System.IO.Pipes;
+using EasyNamedPipes;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.Logging;
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs
deleted file mode 100644
index b9990eee2f..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-#if NETCOREAPP
-using System.Buffers;
-#endif
-
-#if NET
-using Microsoft.Testing.Platform.Helpers;
-using Microsoft.Testing.Platform.Resources;
-#endif
-
-using Microsoft.CodeAnalysis;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-[Embedded]
-internal abstract class BaseSerializer
-{
-#if NETCOREAPP
- protected static string ReadString(Stream stream)
- {
- Span len = stackalloc byte[sizeof(int)];
- stream.ReadExactly(len);
- int stringLen = BitConverter.ToInt32(len);
- byte[] bytes = ArrayPool.Shared.Rent(stringLen);
- try
- {
- stream.ReadExactly(bytes, 0, stringLen);
- return Encoding.UTF8.GetString(bytes, 0, stringLen);
- }
- finally
- {
- ArrayPool.Shared.Return(bytes);
- }
- }
-
- protected static string ReadStringValue(Stream stream, int size)
- {
- byte[] bytes = ArrayPool.Shared.Rent(size);
- try
- {
- stream.ReadExactly(bytes, 0, size);
- return Encoding.UTF8.GetString(bytes, 0, size);
- }
- finally
- {
- ArrayPool.Shared.Return(bytes);
- }
- }
-
- protected static void WriteString(Stream stream, string str)
- {
- int stringutf8TotalBytes = Encoding.UTF8.GetByteCount(str);
- byte[] bytes = ArrayPool.Shared.Rent(stringutf8TotalBytes);
- try
- {
- Span len = stackalloc byte[sizeof(int)];
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(len, stringutf8TotalBytes), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
- stream.Write(len);
-
- Encoding.UTF8.GetBytes(str, bytes);
- stream.Write(bytes, 0, stringutf8TotalBytes);
- }
- finally
- {
- ArrayPool.Shared.Return(bytes);
- }
- }
-
- protected static void WriteStringValue(Stream stream, string str)
- {
- int stringutf8TotalBytes = Encoding.UTF8.GetByteCount(str);
- byte[] bytes = ArrayPool.Shared.Rent(stringutf8TotalBytes);
- try
- {
- Encoding.UTF8.GetBytes(str, bytes);
- stream.Write(bytes, 0, stringutf8TotalBytes);
- }
- finally
- {
- ArrayPool.Shared.Return(bytes);
- }
- }
-
- protected static void WriteStringSize(Stream stream, string str)
- {
- int stringutf8TotalBytes = Encoding.UTF8.GetByteCount(str);
- Span len = stackalloc byte[sizeof(int)];
-
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(len, stringutf8TotalBytes), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(len);
- }
-
- protected static void WriteSize(Stream stream)
- where T : struct
- {
- int sizeInBytes = GetSize();
- Span len = stackalloc byte[sizeof(int)];
-
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(len, sizeInBytes), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(len);
- }
-
- protected static void WriteInt(Stream stream, int value)
- {
- Span bytes = stackalloc byte[sizeof(int)];
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(bytes, value), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(bytes);
- }
-
- protected static void WriteLong(Stream stream, long value)
- {
- Span bytes = stackalloc byte[sizeof(long)];
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(bytes, value), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(bytes);
- }
-
- protected static void WriteUShort(Stream stream, ushort value)
- {
- Span bytes = stackalloc byte[sizeof(ushort)];
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(bytes, value), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(bytes);
- }
-
- protected static void WriteBool(Stream stream, bool value)
- {
- Span bytes = stackalloc byte[sizeof(bool)];
- ApplicationStateGuard.Ensure(BitConverter.TryWriteBytes(bytes, value), PlatformResources.UnexpectedExceptionDuringByteConversionErrorMessage);
-
- stream.Write(bytes);
- }
-
- protected static int ReadInt(Stream stream)
- {
- Span bytes = stackalloc byte[sizeof(int)];
- stream.ReadExactly(bytes);
- return BitConverter.ToInt32(bytes);
- }
-
- protected static long ReadLong(Stream stream)
- {
- Span bytes = stackalloc byte[sizeof(long)];
- stream.ReadExactly(bytes);
- return BitConverter.ToInt64(bytes);
- }
-
- protected static ushort ReadUShort(Stream stream)
- {
- Span bytes = stackalloc byte[sizeof(ushort)];
- stream.ReadExactly(bytes);
- return BitConverter.ToUInt16(bytes);
- }
-
- protected static bool ReadBool(Stream stream)
- {
- Span bytes = stackalloc byte[sizeof(bool)];
- stream.ReadExactly(bytes);
- return BitConverter.ToBoolean(bytes);
- }
-
-#else
- protected static string ReadString(Stream stream)
- {
- byte[] len = new byte[sizeof(int)];
- _ = stream.Read(len, 0, len.Length);
- int length = BitConverter.ToInt32(len, 0);
- byte[] bytes = new byte[length];
- _ = stream.Read(bytes, 0, bytes.Length);
-
- return Encoding.UTF8.GetString(bytes);
- }
-
- protected static string ReadStringValue(Stream stream, int size)
- {
- byte[] bytes = new byte[size];
- _ = stream.Read(bytes, 0, bytes.Length);
-
- return Encoding.UTF8.GetString(bytes);
- }
-
- protected static void WriteString(Stream stream, string str)
- {
- byte[] bytes = Encoding.UTF8.GetBytes(str);
- byte[] len = BitConverter.GetBytes(bytes.Length);
- stream.Write(len, 0, len.Length);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static void WriteStringValue(Stream stream, string str)
- {
- byte[] bytes = Encoding.UTF8.GetBytes(str);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static void WriteStringSize(Stream stream, string str)
- {
- byte[] bytes = Encoding.UTF8.GetBytes(str);
- byte[] len = BitConverter.GetBytes(bytes.Length);
- stream.Write(len, 0, len.Length);
- }
-
- protected static void WriteSize(Stream stream)
- where T : struct
- {
- int sizeInBytes = GetSize();
- byte[] len = BitConverter.GetBytes(sizeInBytes);
- stream.Write(len, 0, len.Length);
- }
-
- protected static void WriteInt(Stream stream, int value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static int ReadInt(Stream stream)
- {
- byte[] bytes = new byte[sizeof(int)];
- _ = stream.Read(bytes, 0, bytes.Length);
- return BitConverter.ToInt32(bytes, 0);
- }
-
- protected static void WriteLong(Stream stream, long value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static void WriteUShort(Stream stream, ushort value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static long ReadLong(Stream stream)
- {
- byte[] bytes = new byte[sizeof(long)];
- _ = stream.Read(bytes, 0, bytes.Length);
- return BitConverter.ToInt64(bytes, 0);
- }
-
- protected static ushort ReadUShort(Stream stream)
- {
- byte[] bytes = new byte[sizeof(ushort)];
- _ = stream.Read(bytes, 0, bytes.Length);
- return BitConverter.ToUInt16(bytes, 0);
- }
-
- protected static void WriteBool(Stream stream, bool value)
- {
- byte[] bytes = BitConverter.GetBytes(value);
- stream.Write(bytes, 0, bytes.Length);
- }
-
- protected static bool ReadBool(Stream stream)
- {
- byte[] bytes = new byte[sizeof(bool)];
- _ = stream.Read(bytes, 0, bytes.Length);
- return BitConverter.ToBoolean(bytes, 0);
- }
-#endif
-
- protected static byte ReadByte(Stream stream) => (byte)stream.ReadByte();
-
- protected static void WriteByte(Stream stream, byte value) => stream.WriteByte(value);
-
- protected static void WriteField(Stream stream, ushort id, string? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteUShort(stream, id);
- WriteStringSize(stream, value);
- WriteStringValue(stream, value);
- }
-
- protected static void WriteField(Stream stream, ushort id, long? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteUShort(stream, id);
- WriteSize(stream);
- WriteLong(stream, value.Value);
- }
-
- protected static void WriteField(Stream stream, ushort id, int? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteUShort(stream, id);
- WriteSize(stream);
- WriteInt(stream, value.Value);
- }
-
- protected static void WriteField(Stream stream, string? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteString(stream, value);
- }
-
- protected static void WriteField(Stream stream, byte? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteByte(stream, value.Value);
- }
-
- protected static void WriteField(Stream stream, ushort id, bool? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteUShort(stream, id);
- WriteSize(stream);
- WriteBool(stream, value.Value);
- }
-
- protected static void WriteField(Stream stream, ushort id, byte? value)
- {
- if (value is null)
- {
- return;
- }
-
- WriteUShort(stream, id);
- WriteSize(stream);
- WriteByte(stream, value.Value);
- }
-
- protected static void SetPosition(Stream stream, long position) => stream.Position = position;
-
- protected static void WriteAtPosition(Stream stream, int value, long position)
- {
- long currentPosition = stream.Position;
- SetPosition(stream, position);
- WriteInt(stream, value);
- SetPosition(stream, currentPosition);
- }
-
- private static int GetSize() => typeof(T) switch
- {
- Type type when type == typeof(int) => sizeof(int),
- Type type when type == typeof(long) => sizeof(long),
- Type type when type == typeof(short) => sizeof(short),
- Type type when type == typeof(bool) => sizeof(bool),
- Type type when type == typeof(byte) => sizeof(byte),
- Type type when type == typeof(long) => sizeof(long),
- _ => 0,
- };
-
- public static bool IsNullOrEmpty(T[]? list) => list is null || list.Length == 0;
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/RegisterSerializers.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/RegisterSerializers.cs
index 03f56780bd..cb8087c4be 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/RegisterSerializers.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/RegisterSerializers.cs
@@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+using EasyNamedPipes.GeneratedSerializers.DotNetTestProtocol;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.IPC.Models;
@@ -29,11 +32,11 @@ public static void RegisterAllSerializers(this NamedPipeBase namedPipeBase)
namedPipeBase.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse));
namedPipeBase.RegisterSerializer(new TestHostProcessExitRequestSerializer(), typeof(TestHostProcessExitRequest));
namedPipeBase.RegisterSerializer(new TestHostProcessPIDRequestSerializer(), typeof(TestHostProcessPIDRequest));
- namedPipeBase.RegisterSerializer(new CommandLineOptionMessagesSerializer(), typeof(CommandLineOptionMessages));
- namedPipeBase.RegisterSerializer(new DiscoveredTestMessagesSerializer(), typeof(DiscoveredTestMessages));
- namedPipeBase.RegisterSerializer(new TestResultMessagesSerializer(), typeof(TestResultMessages));
- namedPipeBase.RegisterSerializer(new FileArtifactMessagesSerializer(), typeof(FileArtifactMessages));
- namedPipeBase.RegisterSerializer(new TestSessionEventSerializer(), typeof(TestSessionEvent));
- namedPipeBase.RegisterSerializer(new HandshakeMessageSerializer(), typeof(HandshakeMessage));
+ namedPipeBase.RegisterSerializer(CommandLineOptionMessagesSerializer.Instance, typeof(CommandLineOptionMessages));
+ namedPipeBase.RegisterSerializer(DiscoveredTestMessagesSerializer.Instance, typeof(DiscoveredTestMessages));
+ namedPipeBase.RegisterSerializer(TestResultMessagesSerializer.Instance, typeof(TestResultMessages));
+ namedPipeBase.RegisterSerializer(FileArtifactMessagesSerializer.Instance, typeof(FileArtifactMessages));
+ namedPipeBase.RegisterSerializer(TestSessionEventSerializer.Instance, typeof(TestSessionEvent));
+ namedPipeBase.RegisterSerializer(HandshakeMessageSerializer.Instance, typeof(HandshakeMessage));
}
}
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessExitRequestSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessExitRequestSerializer.cs
index 09d205d59a..59b77a7701 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessExitRequestSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessExitRequestSerializer.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.IPC.Models;
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessPIDRequestSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessPIDRequestSerializer.cs
index 3981b98101..58b6b6bc98 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessPIDRequestSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/TestHostProcessPIDRequestSerializer.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.IPC.Models;
diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/VoidResponseSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/VoidResponseSerializer.cs
index 701f54c82e..93cc96085e 100644
--- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/VoidResponseSerializer.cs
+++ b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/VoidResponseSerializer.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.CodeAnalysis;
using Microsoft.Testing.Platform.IPC.Models;
diff --git a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj
index 2fde16409a..6189ae65f7 100644
--- a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj
+++ b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj
@@ -85,6 +85,7 @@ This package provides the core platform and the .NET implementation of the proto
+
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
index 11239b8039..b014c68752 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Constants.cs
@@ -38,4 +38,5 @@ internal static class HandshakeMessagePropertyNames
internal static class ProtocolConstants
{
internal const string Version = "1.0.0";
+ internal const string ProtocolName = "DotNetTestProtocol";
}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/CommandLineOptionMessages.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/CommandLineOptionMessages.cs
index 5691de32c3..64799a4f3d 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/CommandLineOptionMessages.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/CommandLineOptionMessages.cs
@@ -1,8 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record CommandLineOptionMessage(string? Name, string? Description, bool? IsHidden, bool? IsBuiltIn);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 31)]
+internal sealed record CommandLineOptionMessage(
+ [property: PipePropertyId(1)] string? Name,
+ [property: PipePropertyId(2)] string? Description,
+ [property: PipePropertyId(3)] bool? IsHidden,
+ [property: PipePropertyId(4)] bool? IsBuiltIn);
-internal sealed record CommandLineOptionMessages(string? ModulePath, CommandLineOptionMessage[]? CommandLineOptionMessageList) : IRequest;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 3)]
+internal sealed record CommandLineOptionMessages(
+ [property: PipePropertyId(1)] string? ModulePath,
+ [property: PipePropertyId(2)] CommandLineOptionMessage[]? CommandLineOptionMessageList) : IRequest;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/DiscoveredTestMessages.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/DiscoveredTestMessages.cs
index 1f2275d1c9..ac25d07f9d 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/DiscoveredTestMessages.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/DiscoveredTestMessages.cs
@@ -1,10 +1,27 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.Extensions.Messages;
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record DiscoveredTestMessage(string? Uid, string? DisplayName, string? FilePath, int? LineNumber, string? Namespace, string? TypeName, string? MethodName, string[]? ParameterTypeFullNames, TestMetadataProperty[] Traits);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 51)]
+internal sealed record DiscoveredTestMessage(
+ [property: PipePropertyId(1)] string? Uid,
+ [property: PipePropertyId(2)] string? DisplayName,
+ [property: PipePropertyId(3)] string? FilePath,
+ [property: PipePropertyId(4)] int? LineNumber,
+ [property: PipePropertyId(5)] string? Namespace,
+ [property: PipePropertyId(6)] string? TypeName,
+ [property: PipePropertyId(7)] string? MethodName,
+ [property: PipePropertyId(8)] string[]? ParameterTypeFullNames,
+ [property: PipePropertyId(9)] TestMetadataProperty[] Traits);
-internal sealed record DiscoveredTestMessages(string? ExecutionId, string? InstanceId, DiscoveredTestMessage[] DiscoveredMessages) : IRequest;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 5)]
+internal sealed record DiscoveredTestMessages(
+ [property: PipePropertyId(1)] string? ExecutionId,
+ [property: PipePropertyId(2)] string? InstanceId,
+ [property: PipePropertyId(3)] DiscoveredTestMessage[] DiscoveredMessages)
+ : IRequest;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/FileArtifactMessages.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/FileArtifactMessages.cs
index 4a0f5a52da..1509a1e9d6 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/FileArtifactMessages.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/FileArtifactMessages.cs
@@ -1,8 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record FileArtifactMessage(string? FullPath, string? DisplayName, string? Description, string? TestUid, string? TestDisplayName, string? SessionUid);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 71)]
+internal sealed record FileArtifactMessage(
+ [property: PipePropertyId(1)] string? FullPath,
+ [property: PipePropertyId(2)] string? DisplayName,
+ [property: PipePropertyId(3)] string? Description,
+ [property: PipePropertyId(4)] string? TestUid,
+ [property: PipePropertyId(5)] string? TestDisplayName,
+ [property: PipePropertyId(6)] string? SessionUid);
-internal sealed record FileArtifactMessages(string? ExecutionId, string? InstanceId, FileArtifactMessage[] FileArtifacts) : IRequest;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 7)]
+internal sealed record FileArtifactMessages(
+ [property: PipePropertyId(1)] string? ExecutionId,
+ [property: PipePropertyId(2)] string? InstanceId,
+ [property: PipePropertyId(3)] FileArtifactMessage[] FileArtifacts)
+ : IRequest;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/HandshakeMessage.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/HandshakeMessage.cs
index 5210c4a278..09c1d5c2e0 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/HandshakeMessage.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/HandshakeMessage.cs
@@ -1,6 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record HandshakeMessage(Dictionary? Properties) : IRequest, IResponse;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 9)]
+internal sealed record HandshakeMessage(
+ [property: PipePropertyId(1)] Dictionary? Properties)
+ : IRequest, IResponse;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestResultMessages.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestResultMessages.cs
index a1ebc94504..109c30d150 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestResultMessages.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestResultMessages.cs
@@ -1,12 +1,43 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record SuccessfulTestResultMessage(string? Uid, string? DisplayName, byte? State, long? Duration, string? Reason, string? StandardOutput, string? ErrorOutput, string? SessionUid);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 61)]
+internal sealed record SuccessfulTestResultMessage(
+ [property: PipePropertyId(1)] string? Uid,
+ [property: PipePropertyId(2)] string? DisplayName,
+ [property: PipePropertyId(3)] byte? State,
+ [property: PipePropertyId(4)] long? Duration,
+ [property: PipePropertyId(5)] string? Reason,
+ [property: PipePropertyId(6)] string? StandardOutput,
+ [property: PipePropertyId(7)] string? ErrorOutput,
+ [property: PipePropertyId(8)] string? SessionUid);
-internal sealed record FailedTestResultMessage(string? Uid, string? DisplayName, byte? State, long? Duration, string? Reason, ExceptionMessage[]? Exceptions, string? StandardOutput, string? ErrorOutput, string? SessionUid);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 62)]
+internal sealed record ExceptionMessage(
+ [property: PipePropertyId(1)] string? ErrorMessage,
+ [property: PipePropertyId(2)] string? ErrorType,
+ [property: PipePropertyId(3)] string? StackTrace);
-internal sealed record ExceptionMessage(string? ErrorMessage, string? ErrorType, string? StackTrace);
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 63)]
+internal sealed record FailedTestResultMessage(
+ [property: PipePropertyId(1)] string? Uid,
+ [property: PipePropertyId(2)] string? DisplayName,
+ [property: PipePropertyId(3)] byte? State,
+ [property: PipePropertyId(4)] long? Duration,
+ [property: PipePropertyId(5)] string? Reason,
+ [property: PipePropertyId(6)] ExceptionMessage[]? Exceptions,
+ [property: PipePropertyId(7)] string? StandardOutput,
+ [property: PipePropertyId(8)] string? ErrorOutput,
+ [property: PipePropertyId(9)] string? SessionUid);
-internal sealed record TestResultMessages(string? ExecutionId, string? InstanceId, SuccessfulTestResultMessage[] SuccessfulTestMessages, FailedTestResultMessage[] FailedTestMessages) : IRequest;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 6)]
+internal sealed record TestResultMessages(
+ [property: PipePropertyId(1)] string? ExecutionId,
+ [property: PipePropertyId(2)] string? InstanceId,
+ [property: PipePropertyId(3)] SuccessfulTestResultMessage[] SuccessfulTestMessages,
+ [property: PipePropertyId(4)] FailedTestResultMessage[] FailedTestMessages)
+ : IRequest;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestSessionEvent.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestSessionEvent.cs
index e1a8954366..9b8bf153ab 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestSessionEvent.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Models/TestSessionEvent.cs
@@ -1,6 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
namespace Microsoft.Testing.Platform.IPC.Models;
-internal sealed record TestSessionEvent(byte? SessionType, string? SessionUid, string? ExecutionId) : IRequest;
+[PipeSerializableMessage(ProtocolConstants.ProtocolName, 8)]
+internal sealed record TestSessionEvent(
+ [property: PipePropertyId(1)] byte? SessionType,
+ [property: PipePropertyId(2)] string? SessionUid,
+ [property: PipePropertyId(3)] string? ExecutionId)
+ : IRequest;
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
index dc61f0c85f..2f751c6fbb 100644
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
+++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/ObjectFieldIds.cs
@@ -22,14 +22,6 @@ internal static class TestHostProcessPIDRequestFieldsId
public const int MessagesSerializerId = 2;
}
-internal static class CommandLineOptionMessagesFieldsId
-{
- public const int MessagesSerializerId = 3;
-
- public const ushort ModulePath = 1;
- public const ushort CommandLineOptionMessageList = 2;
-}
-
internal static class CommandLineOptionMessageFieldsId
{
public const ushort Name = 1;
@@ -38,15 +30,6 @@ internal static class CommandLineOptionMessageFieldsId
public const ushort IsBuiltIn = 4;
}
-internal static class DiscoveredTestMessagesFieldsId
-{
- public const int MessagesSerializerId = 5;
-
- public const ushort ExecutionId = 1;
- public const ushort InstanceId = 2;
- public const ushort DiscoveredTestMessageList = 3;
-}
-
internal static class DiscoveredTestMessageFieldsId
{
public const ushort Uid = 1;
@@ -59,84 +42,3 @@ internal static class DiscoveredTestMessageFieldsId
public const ushort Traits = 8;
public const ushort ParameterTypeFullNames = 9;
}
-
-internal static class TraitMessageFieldsId
-{
- public const ushort Key = 1;
- public const ushort Value = 2;
-}
-
-internal static class TestResultMessagesFieldsId
-{
- public const int MessagesSerializerId = 6;
-
- public const ushort ExecutionId = 1;
- public const ushort InstanceId = 2;
- public const ushort SuccessfulTestMessageList = 3;
- public const ushort FailedTestMessageList = 4;
-}
-
-internal static class SuccessfulTestResultMessageFieldsId
-{
- public const ushort Uid = 1;
- public const ushort DisplayName = 2;
- public const ushort State = 3;
- public const ushort Duration = 4;
- public const ushort Reason = 5;
- public const ushort StandardOutput = 6;
- public const ushort ErrorOutput = 7;
- public const ushort SessionUid = 8;
-}
-
-internal static class FailedTestResultMessageFieldsId
-{
- public const ushort Uid = 1;
- public const ushort DisplayName = 2;
- public const ushort State = 3;
- public const ushort Duration = 4;
- public const ushort Reason = 5;
- public const ushort ExceptionMessageList = 6;
- public const ushort StandardOutput = 7;
- public const ushort ErrorOutput = 8;
- public const ushort SessionUid = 9;
-}
-
-internal static class ExceptionMessageFieldsId
-{
- public const ushort ErrorMessage = 1;
- public const ushort ErrorType = 2;
- public const ushort StackTrace = 3;
-}
-
-internal static class FileArtifactMessagesFieldsId
-{
- public const int MessagesSerializerId = 7;
-
- public const ushort ExecutionId = 1;
- public const ushort InstanceId = 2;
- public const ushort FileArtifactMessageList = 3;
-}
-
-internal static class FileArtifactMessageFieldsId
-{
- public const ushort FullPath = 1;
- public const ushort DisplayName = 2;
- public const ushort Description = 3;
- public const ushort TestUid = 4;
- public const ushort TestDisplayName = 5;
- public const ushort SessionUid = 6;
-}
-
-internal static class TestSessionEventFieldsId
-{
- public const int MessagesSerializerId = 8;
-
- public const ushort SessionType = 1;
- public const ushort SessionUid = 2;
- public const ushort ExecutionId = 3;
-}
-
-internal static class HandshakeMessageFieldsId
-{
- public const int MessagesSerializerId = 9;
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/CommandLineOptionMessagesSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/CommandLineOptionMessagesSerializer.cs
deleted file mode 100644
index 0e75677bd1..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/CommandLineOptionMessagesSerializer.cs
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-/*
- |---FieldCount---| 2 bytes
-
- |---ModuleName Id---| (2 bytes)
- |---ModuleName Size---| (4 bytes)
- |---ModuleName Value---| (n bytes)
-
- |---CommandLineOptionMessageList Id---| (2 bytes)
- |---CommandLineOptionMessageList Size---| (4 bytes)
- |---CommandLineOptionMessageList Value---| (n bytes)
- |---CommandLineOptionMessageList Length---| (4 bytes)
-
- |---CommandLineOptionMessageList[0] FieldCount---| 2 bytes
-
- |---CommandLineOptionMessageList[0].Name Id---| (2 bytes)
- |---CommandLineOptionMessageList[0].Name Size---| (4 bytes)
- |---CommandLineOptionMessageList[0].Name Value---| (n bytes)
-
- |---CommandLineOptionMessageList[0].Description Id---| (2 bytes)
- |---CommandLineOptionMessageList[0].Description Size---| (4 bytes)
- |---CommandLineOptionMessageList[0].Description Value---| (n bytes)
-
- |---CommandLineOptionMessageList[0].IsHidden Id---| (2 bytes)
- |---CommandLineOptionMessageList[0].IsHidden Size---| (4 bytes)
- |---CommandLineOptionMessageList[0].IsHidden Value---| (1 byte)
-
- |---CommandLineOptionMessageList[0].IsBuiltIn Id---| (2 bytes)
- |---CommandLineOptionMessageList[0].IsBuiltIn Size---| (4 bytes)
- |---CommandLineOptionMessageList[0].IsBuiltIn Value---| (1 byte)
- */
-
-internal sealed class CommandLineOptionMessagesSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => CommandLineOptionMessagesFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- string? moduleName = null;
- List? commandLineOptionMessages = null;
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case CommandLineOptionMessagesFieldsId.ModulePath:
- moduleName = ReadStringValue(stream, fieldSize);
- break;
-
- case CommandLineOptionMessagesFieldsId.CommandLineOptionMessageList:
- commandLineOptionMessages = ReadCommandLineOptionMessagesPayload(stream);
- break;
-
- default:
- // If we don't recognize the field id, skip the payload corresponding to that field
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- return new CommandLineOptionMessages(moduleName, commandLineOptionMessages is null ? [] : [.. commandLineOptionMessages]);
- }
-
- private static List ReadCommandLineOptionMessagesPayload(Stream stream)
- {
- List commandLineOptionMessages = [];
-
- int length = ReadInt(stream);
- for (int i = 0; i < length; i++)
- {
- string? name = null, description = null;
- bool? isHidden = null, isBuiltIn = null;
-
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case CommandLineOptionMessageFieldsId.Name:
- name = ReadStringValue(stream, fieldSize);
- break;
-
- case CommandLineOptionMessageFieldsId.Description:
- description = ReadStringValue(stream, fieldSize);
- break;
-
- case CommandLineOptionMessageFieldsId.IsHidden:
- isHidden = ReadBool(stream);
- break;
-
- case CommandLineOptionMessageFieldsId.IsBuiltIn:
- isBuiltIn = ReadBool(stream);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- commandLineOptionMessages.Add(new CommandLineOptionMessage(name, description, isHidden, isBuiltIn));
- }
-
- return commandLineOptionMessages;
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var commandLineOptionMessages = (CommandLineOptionMessages)objectToSerialize;
-
- WriteUShort(stream, GetFieldCount(commandLineOptionMessages));
-
- WriteField(stream, CommandLineOptionMessagesFieldsId.ModulePath, commandLineOptionMessages.ModulePath);
- WriteCommandLineOptionMessagesPayload(stream, commandLineOptionMessages.CommandLineOptionMessageList);
- }
-
- private static void WriteCommandLineOptionMessagesPayload(Stream stream, CommandLineOptionMessage[]? commandLineOptionMessageList)
- {
- if (commandLineOptionMessageList is null || commandLineOptionMessageList.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, CommandLineOptionMessagesFieldsId.CommandLineOptionMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, commandLineOptionMessageList.Length);
- foreach (CommandLineOptionMessage commandLineOptionMessage in commandLineOptionMessageList)
- {
- WriteUShort(stream, GetFieldCount(commandLineOptionMessage));
-
- WriteField(stream, CommandLineOptionMessageFieldsId.Name, commandLineOptionMessage.Name);
- WriteField(stream, CommandLineOptionMessageFieldsId.Description, commandLineOptionMessage.Description);
- WriteField(stream, CommandLineOptionMessageFieldsId.IsHidden, commandLineOptionMessage.IsHidden);
- WriteField(stream, CommandLineOptionMessageFieldsId.IsBuiltIn, commandLineOptionMessage.IsBuiltIn);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static ushort GetFieldCount(CommandLineOptionMessages commandLineOptionMessages) =>
- (ushort)((commandLineOptionMessages.ModulePath is null ? 0 : 1) +
- (IsNullOrEmpty(commandLineOptionMessages.CommandLineOptionMessageList) ? 0 : 1));
-
- private static ushort GetFieldCount(CommandLineOptionMessage commandLineOptionMessage) =>
- (ushort)((commandLineOptionMessage.Name is null ? 0 : 1) +
- (commandLineOptionMessage.Description is null ? 0 : 1) +
- (commandLineOptionMessage.IsHidden is null ? 0 : 1) +
- (commandLineOptionMessage.IsBuiltIn is null ? 0 : 1));
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/DiscoveredTestMessagesSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/DiscoveredTestMessagesSerializer.cs
deleted file mode 100644
index dd0d4f39ae..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/DiscoveredTestMessagesSerializer.cs
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.Extensions.Messages;
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-/*
- |---FieldCount---| 2 bytes
-
- |---ExecutionId Id---| (2 bytes)
- |---ExecutionId Size---| (4 bytes)
- |---ExecutionId Value---| (n bytes)
-
- |---InstanceId---| (2 bytes)
- |---InstanceId Size---| (4 bytes)
- |---InstanceId Value---| (n bytes)
-
- |---DiscoveredTestMessageList Id---| (2 bytes)
- |---DiscoveredTestMessageList Size---| (4 bytes)
- |---DiscoveredTestMessageList Value---| (n bytes)
- |---DiscoveredTestMessageList Length---| (4 bytes)
-
- |---DiscoveredTestMessageList[0] FieldCount---| 2 bytes
-
- |---DiscoveredTestMessageList[0].Uid Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].Uid Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].Uid Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].DisplayName Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].DisplayName Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].DisplayName Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].FilePath Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].FilePath Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].FilePath Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].LineNumber Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].LineNumber Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].LineNumber Value---| (4 bytes)
-
- |---DiscoveredTestMessageList[0].Namespace Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].Namespace Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].Namespace Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].TypeName Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].TypeName Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].TypeName Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].MethodName Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].MethodName Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].MethodName Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].Traits Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].Traits Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].Traits Value---| (n bytes)
- |---DiscoveredTestMessageList[0].Traits Length---| (4 bytes)
-
- |---DiscoveredTestMessageList[0].Trits[0] FieldCount---| 2 bytes
-
- |---DiscoveredTestMessageList[0].Trits[0].Key Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].Trits[0].Key Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].Trits[0].Key Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].Trits[0].Value Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].Trits[0].Value Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].Trits[0].Value Value---| (n bytes)
-
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames Id---| (2 bytes)
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames Value---| (n bytes)
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames Length---| (4 bytes)
-
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames[0].Key Size---| (4 bytes)
- |---DiscoveredTestMessageList[0].ParameterTypeFullNames[0].Key Value---| (n bytes)
-*/
-
-internal sealed class DiscoveredTestMessagesSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => DiscoveredTestMessagesFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- string? executionId = null;
- string? instanceId = null;
- DiscoveredTestMessage[]? discoveredTestMessages = [];
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case DiscoveredTestMessagesFieldsId.ExecutionId:
- executionId = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessagesFieldsId.InstanceId:
- instanceId = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessagesFieldsId.DiscoveredTestMessageList:
- discoveredTestMessages = ReadDiscoveredTestMessagesPayload(stream);
- break;
-
- default:
- // If we don't recognize the field id, skip the payload corresponding to that field
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- return new DiscoveredTestMessages(executionId, instanceId, discoveredTestMessages);
- }
-
- private static DiscoveredTestMessage[] ReadDiscoveredTestMessagesPayload(Stream stream)
- {
- int length = ReadInt(stream);
- var discoveredTestMessages = new DiscoveredTestMessage[length];
- for (int i = 0; i < length; i++)
- {
- string? uid = null;
- string? displayName = null;
- string? filePath = null;
- int? lineNumber = null;
- string? @namespace = null;
- string? typeName = null;
- string? methodName = null;
- TestMetadataProperty[] traits = [];
- string[] parameterTypeFullNames = [];
-
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case DiscoveredTestMessageFieldsId.Uid:
- uid = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.DisplayName:
- displayName = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.FilePath:
- filePath = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.LineNumber:
- lineNumber = ReadInt(stream);
- break;
-
- case DiscoveredTestMessageFieldsId.Namespace:
- @namespace = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.TypeName:
- typeName = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.MethodName:
- methodName = ReadStringValue(stream, fieldSize);
- break;
-
- case DiscoveredTestMessageFieldsId.Traits:
- traits = ReadTraitsPayload(stream);
- break;
-
- case DiscoveredTestMessageFieldsId.ParameterTypeFullNames:
- parameterTypeFullNames = ReadParameterTypeFullNamesPayload(stream);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- discoveredTestMessages[i] = new DiscoveredTestMessage(uid, displayName, filePath, lineNumber, @namespace, typeName, methodName, parameterTypeFullNames, traits);
- }
-
- return discoveredTestMessages;
- }
-
- private static string[] ReadParameterTypeFullNamesPayload(Stream stream)
- {
- int length = ReadInt(stream);
- string[] parameterTypeFullNames = new string[length];
-
- for (int i = 0; i < length; i++)
- {
- parameterTypeFullNames[i] = ReadString(stream);
- }
-
- return parameterTypeFullNames;
- }
-
- private static TestMetadataProperty[] ReadTraitsPayload(Stream stream)
- {
- int length = ReadInt(stream);
- var traits = new TestMetadataProperty[length];
- for (int i = 0; i < length; i++)
- {
- string? key = null;
- string? value = null;
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case TraitMessageFieldsId.Key:
- key = ReadStringValue(stream, fieldSize);
- break;
-
- case TraitMessageFieldsId.Value:
- value = ReadStringValue(stream, fieldSize);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- Guard.NotNull(key);
- Guard.NotNull(value);
- traits[i] = new TestMetadataProperty(key, value);
- }
-
- return traits;
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var discoveredTestMessages = (DiscoveredTestMessages)objectToSerialize;
-
- WriteUShort(stream, GetFieldCount(discoveredTestMessages));
-
- WriteField(stream, DiscoveredTestMessagesFieldsId.ExecutionId, discoveredTestMessages.ExecutionId);
- WriteField(stream, DiscoveredTestMessagesFieldsId.InstanceId, discoveredTestMessages.InstanceId);
- WriteDiscoveredTestMessagesPayload(stream, discoveredTestMessages.DiscoveredMessages);
- }
-
- private static void WriteDiscoveredTestMessagesPayload(Stream stream, DiscoveredTestMessage[]? discoveredTestMessageList)
- {
- if (discoveredTestMessageList is null || discoveredTestMessageList.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, DiscoveredTestMessagesFieldsId.DiscoveredTestMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, discoveredTestMessageList.Length);
- foreach (DiscoveredTestMessage discoveredTestMessage in discoveredTestMessageList)
- {
- WriteUShort(stream, GetFieldCount(discoveredTestMessage));
-
- WriteField(stream, DiscoveredTestMessageFieldsId.Uid, discoveredTestMessage.Uid);
- WriteField(stream, DiscoveredTestMessageFieldsId.DisplayName, discoveredTestMessage.DisplayName);
- WriteField(stream, DiscoveredTestMessageFieldsId.FilePath, discoveredTestMessage.FilePath);
- WriteField(stream, DiscoveredTestMessageFieldsId.LineNumber, discoveredTestMessage.LineNumber);
- WriteField(stream, DiscoveredTestMessageFieldsId.Namespace, discoveredTestMessage.Namespace);
- WriteField(stream, DiscoveredTestMessageFieldsId.TypeName, discoveredTestMessage.TypeName);
- WriteField(stream, DiscoveredTestMessageFieldsId.MethodName, discoveredTestMessage.MethodName);
- WriteParameterTypeFullNamesPayload(stream, discoveredTestMessage.ParameterTypeFullNames);
- WriteTraitsPayload(stream, discoveredTestMessage.Traits);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static void WriteTraitsPayload(Stream stream, TestMetadataProperty[]? traits)
- {
- if (traits is null || traits.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, DiscoveredTestMessageFieldsId.Traits);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, traits.Length);
- foreach (TestMetadataProperty trait in traits)
- {
- WriteUShort(stream, GetFieldCount(trait));
-
- WriteField(stream, TraitMessageFieldsId.Key, trait.Key);
- WriteField(stream, TraitMessageFieldsId.Value, trait.Value);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static void WriteParameterTypeFullNamesPayload(Stream stream, string[]? parameterTypeFullNames)
- {
- if (parameterTypeFullNames is null || parameterTypeFullNames.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, DiscoveredTestMessageFieldsId.ParameterTypeFullNames);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, parameterTypeFullNames.Length);
- foreach (string parameterTypeFullName in parameterTypeFullNames)
- {
- WriteString(stream, parameterTypeFullName);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static ushort GetFieldCount(DiscoveredTestMessages discoveredTestMessages) =>
- (ushort)((discoveredTestMessages.ExecutionId is null ? 0 : 1) +
- (discoveredTestMessages.InstanceId is null ? 0 : 1) +
- (IsNullOrEmpty(discoveredTestMessages.DiscoveredMessages) ? 0 : 1));
-
- private static ushort GetFieldCount(DiscoveredTestMessage discoveredTestMessage) =>
- (ushort)((discoveredTestMessage.Uid is null ? 0 : 1) +
- (discoveredTestMessage.DisplayName is null ? 0 : 1) +
- (discoveredTestMessage.FilePath is null ? 0 : 1) +
- (discoveredTestMessage.LineNumber is null ? 0 : 1) +
- (discoveredTestMessage.Namespace is null ? 0 : 1) +
- (discoveredTestMessage.TypeName is null ? 0 : 1) +
- (discoveredTestMessage.MethodName is null ? 0 : 1) +
- (IsNullOrEmpty(discoveredTestMessage.ParameterTypeFullNames) ? 0 : 1) +
- (IsNullOrEmpty(discoveredTestMessage.Traits) ? 0 : 1));
-
- private static ushort GetFieldCount(TestMetadataProperty trait) =>
- (ushort)((trait.Key is null ? 0 : 1) +
- (trait.Value is null ? 0 : 1));
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/FileArtifactMessagesSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/FileArtifactMessagesSerializer.cs
deleted file mode 100644
index 614fe806bc..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/FileArtifactMessagesSerializer.cs
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-/*
- |---FieldCount---| 2 bytes
-
- |---ExecutionId Id---| (2 bytes)
- |---ExecutionId Size---| (4 bytes)
- |---ExecutionId Value---| (n bytes)
-
- |---InstanceId---| (2 bytes)
- |---InstanceId Size---| (4 bytes)
- |---InstanceId Value---| (n bytes)
-
- |---FileArtifactMessageList Id---| (2 bytes)
- |---FileArtifactMessageList Size---| (4 bytes)
- |---FileArtifactMessageList Value---| (n bytes)
- |---FileArtifactMessageList Length---| (4 bytes)
-
- |---FileArtifactMessageList[0] FieldCount---| 2 bytes
-
- |---FileArtifactMessageList[0].FullPath Id---| (2 bytes)
- |---FileArtifactMessageList[0].FullPath Size---| (4 bytes)
- |---FileArtifactMessageList[0].FullPath Value---| (n bytes)
-
- |---FileArtifactMessageList[0].DisplayName Id---| (2 bytes)
- |---FileArtifactMessageList[0].DisplayName Size---| (4 bytes)
- |---FileArtifactMessageList[0].DisplayName Value---| (n bytes)
-
- |---FileArtifactMessageList[0].Description Id---| (2 bytes)
- |---FileArtifactMessageList[0].Description Size---| (4 bytes)
- |---FileArtifactMessageList[0].Description Value---| (n bytes)
-
- |---FileArtifactMessageList[0].TestUid Id---| (2 bytes)
- |---FileArtifactMessageList[0].TestUid Size---| (4 bytes)
- |---FileArtifactMessageList[0].TestUid Value---| (n bytes)
-
- |---FileArtifactMessageList[0].TestDisplayName Id---| (2 bytes)
- |---FileArtifactMessageList[0].TestDisplayName Size---| (4 bytes)
- |---FileArtifactMessageList[0].TestDisplayName Value---| (n bytes)
-
- |---FileArtifactMessageList[0].SessionUid Id---| (2 bytes)
- |---FileArtifactMessageList[0].SessionUid Size---| (4 bytes)
- |---FileArtifactMessageList[0].SessionUid Value---| (n bytes)
- */
-
-internal sealed class FileArtifactMessagesSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => FileArtifactMessagesFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- string? executionId = null;
- string? instanceId = null;
- List? fileArtifactMessages = null;
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case FileArtifactMessagesFieldsId.ExecutionId:
- executionId = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessagesFieldsId.InstanceId:
- instanceId = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessagesFieldsId.FileArtifactMessageList:
- fileArtifactMessages = ReadFileArtifactMessagesPayload(stream);
- break;
-
- default:
- // If we don't recognize the field id, skip the payload corresponding to that field
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- return new FileArtifactMessages(executionId, instanceId, fileArtifactMessages is null ? [] : [.. fileArtifactMessages]);
- }
-
- private static List ReadFileArtifactMessagesPayload(Stream stream)
- {
- List fileArtifactMessages = [];
-
- int length = ReadInt(stream);
- for (int i = 0; i < length; i++)
- {
- string? fullPath = null, displayName = null, description = null, testUid = null, testDisplayName = null, sessionUid = null;
-
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case FileArtifactMessageFieldsId.FullPath:
- fullPath = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessageFieldsId.DisplayName:
- displayName = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessageFieldsId.Description:
- description = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessageFieldsId.TestUid:
- testUid = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessageFieldsId.TestDisplayName:
- testDisplayName = ReadStringValue(stream, fieldSize);
- break;
-
- case FileArtifactMessageFieldsId.SessionUid:
- sessionUid = ReadStringValue(stream, fieldSize);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- fileArtifactMessages.Add(new FileArtifactMessage(fullPath, displayName, description, testUid, testDisplayName, sessionUid));
- }
-
- return fileArtifactMessages;
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var fileArtifactMessages = (FileArtifactMessages)objectToSerialize;
-
- WriteUShort(stream, GetFieldCount(fileArtifactMessages));
-
- WriteField(stream, FileArtifactMessagesFieldsId.ExecutionId, fileArtifactMessages.ExecutionId);
- WriteField(stream, FileArtifactMessagesFieldsId.InstanceId, fileArtifactMessages.InstanceId);
- WriteFileArtifactMessagesPayload(stream, fileArtifactMessages.FileArtifacts);
- }
-
- private static void WriteFileArtifactMessagesPayload(Stream stream, FileArtifactMessage[]? fileArtifactMessageList)
- {
- if (fileArtifactMessageList is null || fileArtifactMessageList.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, FileArtifactMessagesFieldsId.FileArtifactMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, fileArtifactMessageList.Length);
- foreach (FileArtifactMessage fileArtifactMessage in fileArtifactMessageList)
- {
- WriteUShort(stream, GetFieldCount(fileArtifactMessage));
-
- WriteField(stream, FileArtifactMessageFieldsId.FullPath, fileArtifactMessage.FullPath);
- WriteField(stream, FileArtifactMessageFieldsId.DisplayName, fileArtifactMessage.DisplayName);
- WriteField(stream, FileArtifactMessageFieldsId.Description, fileArtifactMessage.Description);
- WriteField(stream, FileArtifactMessageFieldsId.TestUid, fileArtifactMessage.TestUid);
- WriteField(stream, FileArtifactMessageFieldsId.TestDisplayName, fileArtifactMessage.TestDisplayName);
- WriteField(stream, FileArtifactMessageFieldsId.SessionUid, fileArtifactMessage.SessionUid);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static ushort GetFieldCount(FileArtifactMessages fileArtifactMessages) =>
- (ushort)((fileArtifactMessages.ExecutionId is null ? 0 : 1) +
- (fileArtifactMessages.InstanceId is null ? 0 : 1) +
- (IsNullOrEmpty(fileArtifactMessages.FileArtifacts) ? 0 : 1));
-
- private static ushort GetFieldCount(FileArtifactMessage fileArtifactMessage) =>
- (ushort)((fileArtifactMessage.FullPath is null ? 0 : 1) +
- (fileArtifactMessage.DisplayName is null ? 0 : 1) +
- (fileArtifactMessage.Description is null ? 0 : 1) +
- (fileArtifactMessage.TestUid is null ? 0 : 1) +
- (fileArtifactMessage.TestDisplayName is null ? 0 : 1) +
- (fileArtifactMessage.SessionUid is null ? 0 : 1));
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs
deleted file mode 100644
index 554ae3b12d..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-internal sealed class HandshakeMessageSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => HandshakeMessageFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- Dictionary properties = [];
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- properties.Add(ReadByte(stream), ReadString(stream));
- }
-
- return new HandshakeMessage(properties);
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var handshakeMessage = (HandshakeMessage)objectToSerialize;
-
- // Deserializer always expected fieldCount to be present.
- // We must write the count even if Properties is null or empty.
- WriteUShort(stream, (ushort)(handshakeMessage.Properties?.Count ?? 0));
-
- if (handshakeMessage.Properties is null)
- {
- return;
- }
-
- foreach ((byte key, string value) in handshakeMessage.Properties)
- {
- WriteField(stream, key);
- WriteField(stream, value);
- }
- }
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestResultMessagesSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestResultMessagesSerializer.cs
deleted file mode 100644
index 6535d43e12..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestResultMessagesSerializer.cs
+++ /dev/null
@@ -1,472 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-/*
- |---FieldCount---| 2 bytes
-
- |---ExecutionId Id---| (2 bytes)
- |---ExecutionId Size---| (4 bytes)
- |---ExecutionId Value---| (n bytes)
-
- |---InstanceId Id---| (2 bytes)
- |---InstanceId Size---| (4 bytes)
- |---InstanceId Value---| (n bytes)
-
- |---SuccessfulTestMessageList Id---| (2 bytes)
- |---SuccessfulTestMessageList Size---| (4 bytes)
- |---SuccessfulTestMessageList Value---| (n bytes)
- |---SuccessfulTestMessageList Length---| (4 bytes)
-
- |---SuccessfulTestMessageList[0] FieldCount---| 2 bytes
-
- |---SuccessfulTestMessageList[0].Uid Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].Uid Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].Uid Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].DisplayName Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].DisplayName Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].DisplayName Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].State Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].State Size---| (1 byte)
- |---SuccessfulTestMessageList[0].State Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].Duration Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].Duration Size---| (8 bytes)
- |---SuccessfulTestMessageList[0].Duration Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].Reason Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].Reason Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].Reason Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].StandardOutput Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].StandardOutput Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].StandardOutput Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].StandardError Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].StandardError Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].StandardError Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].SessionUid Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].SessionUid Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].SessionUid Value---| (n bytes)
-
- |---FailedTestMessageList Id---| (2 bytes)
- |---FailedTestMessageList Size---| (4 bytes)
- |---FailedTestMessageList Value---| (n bytes)
- |---FailedTestMessageList Length---| (4 bytes)
-
- |---FailedTestMessageList[0] FieldCount---| 2 bytes
-
- |---FailedTestMessageList[0].Uid Id---| (2 bytes)
- |---FailedTestMessageList[0].Uid Size---| (4 bytes)
- |---FailedTestMessageList[0].Uid Value---| (n bytes)
-
- |---FailedTestMessageList[0].DisplayName Id---| (2 bytes)
- |---FailedTestMessageList[0].DisplayName Size---| (4 bytes)
- |---FailedTestMessageList[0].DisplayName Value---| (n bytes)
-
- |---FailedTestMessageList[0].State Id---| (2 bytes)
- |---FailedTestMessageList[0].State Size---| (1 byte)
- |---FailedTestMessageList[0].State Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].Duration Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].Duration Size---| (8 bytes)
- |---SuccessfulTestMessageList[0].Duration Value---| (n bytes)
-
- |---FailedTestMessageList[0].Reason Id---| (2 bytes)
- |---FailedTestMessageList[0].Reason Size---| (4 bytes)
- |---FailedTestMessageList[0].Reason Value---| (n bytes)
-
- |---FailedTestMessageList[0].ErrorMessage Id---| (2 bytes)
- |---FailedTestMessageList[0].ErrorMessage Size---| (4 bytes)
- |---FailedTestMessageList[0].ErrorMessage Value---| (n bytes)
-
- |---FailedTestMessageList[0].ErrorStackTrace Id---| (2 bytes)
- |---FailedTestMessageList[0].ErrorStackTrace Size---| (4 bytes)
- |---FailedTestMessageList[0].ErrorStackTrace Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].StandardOutput Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].StandardOutput Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].StandardOutput Value---| (n bytes)
-
- |---SuccessfulTestMessageList[0].StandardError Id---| (2 bytes)
- |---SuccessfulTestMessageList[0].StandardError Size---| (4 bytes)
- |---SuccessfulTestMessageList[0].StandardError Value---| (n bytes)
-
- |---FailedTestMessageList[0].SessionUid Id---| (2 bytes)
- |---FailedTestMessageList[0].SessionUid Size---| (4 bytes)
- |---FailedTestMessageList[0].SessionUid Value---| (n bytes)
- */
-
-internal sealed class TestResultMessagesSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => TestResultMessagesFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- string? executionId = null;
- string? instanceId = null;
- List? successfulTestResultMessages = null;
- List? failedTestResultMessages = null;
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case TestResultMessagesFieldsId.ExecutionId:
- executionId = ReadStringValue(stream, fieldSize);
- break;
-
- case TestResultMessagesFieldsId.InstanceId:
- instanceId = ReadStringValue(stream, fieldSize);
- break;
-
- case TestResultMessagesFieldsId.SuccessfulTestMessageList:
- successfulTestResultMessages = ReadSuccessfulTestMessagesPayload(stream);
- break;
-
- case TestResultMessagesFieldsId.FailedTestMessageList:
- failedTestResultMessages = ReadFailedTestMessagesPayload(stream);
- break;
-
- default:
- // If we don't recognize the field id, skip the payload corresponding to that field
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- return new TestResultMessages(
- executionId,
- instanceId,
- successfulTestResultMessages is null ? [] : [.. successfulTestResultMessages],
- failedTestResultMessages is null ? [] : [.. failedTestResultMessages]);
- }
-
- private static List ReadSuccessfulTestMessagesPayload(Stream stream)
- {
- List successfulTestResultMessages = [];
-
- int length = ReadInt(stream);
- for (int i = 0; i < length; i++)
- {
- string? uid = null, displayName = null, reason = null, standardOutput = null, errorOutput = null, sessionUid = null;
- byte? state = null;
- long? duration = null;
-
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case SuccessfulTestResultMessageFieldsId.Uid:
- uid = ReadStringValue(stream, fieldSize);
- break;
-
- case SuccessfulTestResultMessageFieldsId.DisplayName:
- displayName = ReadStringValue(stream, fieldSize);
- break;
-
- case SuccessfulTestResultMessageFieldsId.State:
- state = ReadByte(stream);
- break;
-
- case SuccessfulTestResultMessageFieldsId.Duration:
- duration = ReadLong(stream);
- break;
-
- case SuccessfulTestResultMessageFieldsId.Reason:
- reason = ReadStringValue(stream, fieldSize);
- break;
-
- case SuccessfulTestResultMessageFieldsId.StandardOutput:
- standardOutput = ReadStringValue(stream, fieldSize);
- break;
-
- case SuccessfulTestResultMessageFieldsId.ErrorOutput:
- errorOutput = ReadStringValue(stream, fieldSize);
- break;
-
- case SuccessfulTestResultMessageFieldsId.SessionUid:
- sessionUid = ReadStringValue(stream, fieldSize);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- successfulTestResultMessages.Add(new SuccessfulTestResultMessage(uid, displayName, state, duration, reason, standardOutput, errorOutput, sessionUid));
- }
-
- return successfulTestResultMessages;
- }
-
- private static List ReadFailedTestMessagesPayload(Stream stream)
- {
- List failedTestResultMessages = [];
-
- int length = ReadInt(stream);
- for (int i = 0; i < length; i++)
- {
- string? uid = null, displayName = null, reason = null, sessionUid = null, standardOutput = null, errorOutput = null;
- ExceptionMessage[] exceptionMessages = [];
- byte? state = null;
- long? duration = null;
-
- int fieldCount = ReadUShort(stream);
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case FailedTestResultMessageFieldsId.Uid:
- uid = ReadStringValue(stream, fieldSize);
- break;
-
- case FailedTestResultMessageFieldsId.DisplayName:
- displayName = ReadStringValue(stream, fieldSize);
- break;
-
- case FailedTestResultMessageFieldsId.State:
- state = ReadByte(stream);
- break;
-
- case FailedTestResultMessageFieldsId.Duration:
- duration = ReadLong(stream);
- break;
-
- case FailedTestResultMessageFieldsId.Reason:
- reason = ReadStringValue(stream, fieldSize);
- break;
-
- case FailedTestResultMessageFieldsId.ExceptionMessageList:
- exceptionMessages = ReadExceptionMessagesPayload(stream);
- break;
-
- case FailedTestResultMessageFieldsId.StandardOutput:
- standardOutput = ReadStringValue(stream, fieldSize);
- break;
-
- case FailedTestResultMessageFieldsId.ErrorOutput:
- errorOutput = ReadStringValue(stream, fieldSize);
- break;
-
- case FailedTestResultMessageFieldsId.SessionUid:
- sessionUid = ReadStringValue(stream, fieldSize);
- break;
-
- default:
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- failedTestResultMessages.Add(new FailedTestResultMessage(uid, displayName, state, duration, reason, exceptionMessages, standardOutput, errorOutput, sessionUid));
- }
-
- return failedTestResultMessages;
- }
-
- private static ExceptionMessage[] ReadExceptionMessagesPayload(Stream stream)
- {
- var exceptionMessages = new List();
-
- int length = ReadInt(stream);
- for (int i = 0; i < length; i++)
- {
- int fieldCount = ReadUShort(stream);
-
- string? errorMessage = null;
- string? errorType = null;
- string? stackTrace = null;
-
- for (int j = 0; j < fieldCount; j++)
- {
- int fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case ExceptionMessageFieldsId.ErrorMessage:
- errorMessage = ReadStringValue(stream, fieldSize);
- break;
-
- case ExceptionMessageFieldsId.ErrorType:
- errorType = ReadStringValue(stream, fieldSize);
- break;
-
- case ExceptionMessageFieldsId.StackTrace:
- stackTrace = ReadStringValue(stream, fieldSize);
- break;
- }
- }
-
- exceptionMessages.Add(new ExceptionMessage(errorMessage, errorType, stackTrace));
- }
-
- return [.. exceptionMessages];
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var testResultMessages = (TestResultMessages)objectToSerialize;
-
- WriteUShort(stream, GetFieldCount(testResultMessages));
-
- WriteField(stream, TestResultMessagesFieldsId.ExecutionId, testResultMessages.ExecutionId);
- WriteField(stream, TestResultMessagesFieldsId.InstanceId, testResultMessages.InstanceId);
- WriteSuccessfulTestMessagesPayload(stream, testResultMessages.SuccessfulTestMessages);
- WriteFailedTestMessagesPayload(stream, testResultMessages.FailedTestMessages);
- }
-
- private static void WriteSuccessfulTestMessagesPayload(Stream stream, SuccessfulTestResultMessage[]? successfulTestResultMessages)
- {
- if (successfulTestResultMessages is null || successfulTestResultMessages.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, TestResultMessagesFieldsId.SuccessfulTestMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, successfulTestResultMessages.Length);
- foreach (SuccessfulTestResultMessage successfulTestResultMessage in successfulTestResultMessages)
- {
- WriteUShort(stream, GetFieldCount(successfulTestResultMessage));
-
- WriteField(stream, SuccessfulTestResultMessageFieldsId.Uid, successfulTestResultMessage.Uid);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.DisplayName, successfulTestResultMessage.DisplayName);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.State, successfulTestResultMessage.State);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.Duration, successfulTestResultMessage.Duration);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.Reason, successfulTestResultMessage.Reason);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.StandardOutput, successfulTestResultMessage.StandardOutput);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.ErrorOutput, successfulTestResultMessage.ErrorOutput);
- WriteField(stream, SuccessfulTestResultMessageFieldsId.SessionUid, successfulTestResultMessage.SessionUid);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static void WriteFailedTestMessagesPayload(Stream stream, FailedTestResultMessage[]? failedTestResultMessages)
- {
- if (failedTestResultMessages is null || failedTestResultMessages.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, TestResultMessagesFieldsId.FailedTestMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, failedTestResultMessages.Length);
- foreach (FailedTestResultMessage failedTestResultMessage in failedTestResultMessages)
- {
- WriteUShort(stream, GetFieldCount(failedTestResultMessage));
-
- WriteField(stream, FailedTestResultMessageFieldsId.Uid, failedTestResultMessage.Uid);
- WriteField(stream, FailedTestResultMessageFieldsId.DisplayName, failedTestResultMessage.DisplayName);
- WriteField(stream, FailedTestResultMessageFieldsId.State, failedTestResultMessage.State);
- WriteField(stream, FailedTestResultMessageFieldsId.Duration, failedTestResultMessage.Duration);
- WriteField(stream, FailedTestResultMessageFieldsId.Reason, failedTestResultMessage.Reason);
- WriteExceptionMessagesPayload(stream, failedTestResultMessage.Exceptions);
- WriteField(stream, FailedTestResultMessageFieldsId.StandardOutput, failedTestResultMessage.StandardOutput);
- WriteField(stream, FailedTestResultMessageFieldsId.ErrorOutput, failedTestResultMessage.ErrorOutput);
- WriteField(stream, FailedTestResultMessageFieldsId.SessionUid, failedTestResultMessage.SessionUid);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static void WriteExceptionMessagesPayload(Stream stream, ExceptionMessage[]? exceptionMessages)
- {
- if (exceptionMessages is null || exceptionMessages.Length == 0)
- {
- return;
- }
-
- WriteUShort(stream, FailedTestResultMessageFieldsId.ExceptionMessageList);
-
- // We will reserve an int (4 bytes)
- // so that we fill the size later, once we write the payload
- WriteInt(stream, 0);
-
- long before = stream.Position;
- WriteInt(stream, exceptionMessages.Length);
- foreach (ExceptionMessage exceptionMessage in exceptionMessages)
- {
- WriteUShort(stream, GetFieldCount(exceptionMessage));
-
- WriteField(stream, ExceptionMessageFieldsId.ErrorMessage, exceptionMessage.ErrorMessage);
- WriteField(stream, ExceptionMessageFieldsId.ErrorType, exceptionMessage.ErrorType);
- WriteField(stream, ExceptionMessageFieldsId.StackTrace, exceptionMessage.StackTrace);
- }
-
- // NOTE: We are able to seek only if we are using a MemoryStream
- // thus, the seek operation is fast as we are only changing the value of a property
- WriteAtPosition(stream, (int)(stream.Position - before), before - sizeof(int));
- }
-
- private static ushort GetFieldCount(TestResultMessages testResultMessages) =>
- (ushort)((testResultMessages.ExecutionId is null ? 0 : 1) +
- (testResultMessages.InstanceId is null ? 0 : 1) +
- (IsNullOrEmpty(testResultMessages.SuccessfulTestMessages) ? 0 : 1) +
- (IsNullOrEmpty(testResultMessages.FailedTestMessages) ? 0 : 1));
-
- private static ushort GetFieldCount(SuccessfulTestResultMessage successfulTestResultMessage) =>
- (ushort)((successfulTestResultMessage.Uid is null ? 0 : 1) +
- (successfulTestResultMessage.DisplayName is null ? 0 : 1) +
- (successfulTestResultMessage.State is null ? 0 : 1) +
- (successfulTestResultMessage.Duration is null ? 0 : 1) +
- (successfulTestResultMessage.Reason is null ? 0 : 1) +
- (successfulTestResultMessage.StandardOutput is null ? 0 : 1) +
- (successfulTestResultMessage.ErrorOutput is null ? 0 : 1) +
- (successfulTestResultMessage.SessionUid is null ? 0 : 1));
-
- private static ushort GetFieldCount(FailedTestResultMessage failedTestResultMessage) =>
- (ushort)((failedTestResultMessage.Uid is null ? 0 : 1) +
- (failedTestResultMessage.DisplayName is null ? 0 : 1) +
- (failedTestResultMessage.State is null ? 0 : 1) +
- (failedTestResultMessage.Duration is null ? 0 : 1) +
- (failedTestResultMessage.Reason is null ? 0 : 1) +
- (IsNullOrEmpty(failedTestResultMessage.Exceptions) ? 0 : 1) +
- (failedTestResultMessage.StandardOutput is null ? 0 : 1) +
- (failedTestResultMessage.ErrorOutput is null ? 0 : 1) +
- (failedTestResultMessage.SessionUid is null ? 0 : 1));
-
- private static ushort GetFieldCount(ExceptionMessage exceptionMessage) =>
- (ushort)((exceptionMessage.ErrorMessage is null ? 0 : 1) +
- (exceptionMessage.ErrorType is null ? 0 : 1) +
- (exceptionMessage.StackTrace is null ? 0 : 1));
-}
diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestSessionEventSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestSessionEventSerializer.cs
deleted file mode 100644
index 0862b3f69f..0000000000
--- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/TestSessionEventSerializer.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using Microsoft.Testing.Platform.IPC.Models;
-
-namespace Microsoft.Testing.Platform.IPC.Serializers;
-
-/*
- |---FieldCount---| 2 bytes
-
- |---Type Id---| (2 bytes)
- |---Type Size---| (4 bytes)
- |---Type Value---| (n bytes)
-
- |---SessionUid Id---| (2 bytes)
- |---SessionUid Size---| (4 bytes)
- |---SessionUid Value---| (n bytes)
-
- |---ExecutionId Id---| (2 bytes)
- |---ExecutionId Size---| (4 bytes)
- |---ExecutionId Value---| (n bytes)
-*/
-
-internal sealed class TestSessionEventSerializer : BaseSerializer, INamedPipeSerializer
-{
- public int Id => TestSessionEventFieldsId.MessagesSerializerId;
-
- public object Deserialize(Stream stream)
- {
- byte? type = null;
- string? sessionUid = null;
- string? executionId = null;
-
- ushort fieldCount = ReadUShort(stream);
-
- for (int i = 0; i < fieldCount; i++)
- {
- ushort fieldId = ReadUShort(stream);
- int fieldSize = ReadInt(stream);
-
- switch (fieldId)
- {
- case TestSessionEventFieldsId.SessionType:
- type = ReadByte(stream);
- break;
-
- case TestSessionEventFieldsId.SessionUid:
- sessionUid = ReadStringValue(stream, fieldSize);
- break;
-
- case TestSessionEventFieldsId.ExecutionId:
- executionId = ReadStringValue(stream, fieldSize);
- break;
-
- default:
- // If we don't recognize the field id, skip the payload corresponding to that field
- SetPosition(stream, stream.Position + fieldSize);
- break;
- }
- }
-
- return new TestSessionEvent(type, sessionUid, executionId);
- }
-
- public void Serialize(object objectToSerialize, Stream stream)
- {
- RoslynDebug.Assert(stream.CanSeek, "We expect a seekable stream.");
-
- var testSessionEvent = (TestSessionEvent)objectToSerialize;
-
- WriteUShort(stream, GetFieldCount(testSessionEvent));
-
- WriteField(stream, TestSessionEventFieldsId.SessionType, testSessionEvent.SessionType);
- WriteField(stream, TestSessionEventFieldsId.SessionUid, testSessionEvent.SessionUid);
- WriteField(stream, TestSessionEventFieldsId.ExecutionId, testSessionEvent.ExecutionId);
- }
-
- private static ushort GetFieldCount(TestSessionEvent testSessionEvent) =>
- (ushort)((testSessionEvent.SessionType is null ? 0 : 1) +
- (testSessionEvent.SessionUid is null ? 0 : 1) +
- (testSessionEvent.ExecutionId is null ? 0 : 1));
-}
diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
index bcd8df1ced..35be6e95d2 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes;
+
using Microsoft.Testing.Platform.Helpers;
using Microsoft.Testing.Platform.IPC;
using Microsoft.Testing.Platform.IPC.Models;
diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs
index 809a396a18..e06b13d067 100644
--- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs
+++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs
@@ -1,8 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+using EasyNamedPipes.GeneratedSerializers.DotNetTestProtocol;
+
using Microsoft.Testing.Platform.IPC.Models;
-using Microsoft.Testing.Platform.IPC.Serializers;
namespace Microsoft.Testing.Platform.UnitTests;
@@ -17,9 +18,9 @@ public void TestResultMessagesSerializeDeserialize()
var message = new TestResultMessages("executionId", "instanceId", [success], [fail]);
var stream = new MemoryStream();
- new TestResultMessagesSerializer().Serialize(message, stream);
+ TestResultMessagesSerializer.Instance.Serialize(message, stream);
stream.Seek(0, SeekOrigin.Begin);
- var actual = (TestResultMessages)new TestResultMessagesSerializer().Deserialize(stream);
+ var actual = (TestResultMessages)TestResultMessagesSerializer.Instance.Deserialize(stream);
Assert.AreEqual(message.ExecutionId, actual.ExecutionId);
#if NET8_0_OR_GREATER
Assert.AreEqual(System.Text.Json.JsonSerializer.Serialize(message), System.Text.Json.JsonSerializer.Serialize(actual));
@@ -30,7 +31,7 @@ public void TestResultMessagesSerializeDeserialize()
[TestMethod]
public void DiscoveredTestMessagesSerializeDeserialize()
{
- var serializer = new DiscoveredTestMessagesSerializer();
+ var serializer = DiscoveredTestMessagesSerializer.Instance;
var stream = new MemoryStream();
var message = new DiscoveredTestMessages(
@@ -93,9 +94,9 @@ public void HandshakeMessageWithProperties()
});
var stream = new MemoryStream();
- new HandshakeMessageSerializer().Serialize(message, stream);
+ HandshakeMessageSerializer.Instance.Serialize(message, stream);
stream.Seek(0, SeekOrigin.Begin);
- var actual = (HandshakeMessage)new HandshakeMessageSerializer().Deserialize(stream);
+ var actual = (HandshakeMessage)HandshakeMessageSerializer.Instance.Deserialize(stream);
Assert.IsNotNull(actual.Properties);
Assert.IsNotNull(message.Properties);
@@ -119,9 +120,9 @@ public void HandshakeMessageWithEmptyProperties()
var message = new HandshakeMessage([]);
var stream = new MemoryStream();
- new HandshakeMessageSerializer().Serialize(message, stream);
+ HandshakeMessageSerializer.Instance.Serialize(message, stream);
stream.Seek(0, SeekOrigin.Begin);
- var actual = (HandshakeMessage)new HandshakeMessageSerializer().Deserialize(stream);
+ var actual = (HandshakeMessage)HandshakeMessageSerializer.Instance.Deserialize(stream);
Assert.IsNotNull(actual.Properties);
Assert.IsNotNull(message.Properties);
@@ -136,9 +137,9 @@ public void HandshakeMessageWithNullProperties()
var message = new HandshakeMessage(null);
var stream = new MemoryStream();
- new HandshakeMessageSerializer().Serialize(message, stream);
+ HandshakeMessageSerializer.Instance.Serialize(message, stream);
stream.Seek(0, SeekOrigin.Begin);
- var actual = (HandshakeMessage)new HandshakeMessageSerializer().Deserialize(stream);
+ var actual = (HandshakeMessage)HandshakeMessageSerializer.Instance.Deserialize(stream);
Assert.IsNotNull(actual.Properties);
Assert.IsNull(message.Properties);