Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle Test Information from the New Testing Platform #42494

Merged
merged 16 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/Cli/dotnet/commands/dotnet-test/CliConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@ internal static class CliConstants
public const string ServerOptionValue = "dotnettestcli";

public const string MSBuildExeName = "MSBuild.dll";
}

internal static class TestStates
{
internal const string Passed = "Passed";

internal const string Skipped = "Skipped";

internal const string Failed = "Failed";

internal const string Error = "Error";

internal const string Timeout = "Timeout";

internal const string Cancelled = "Cancelled";
}

internal static class SessionEventTypes
{
internal const string TestSessionStart = "TestSessionStart";
internal const string TestSessionEnd = "TestSessionEnd";
}

internal static class HandshakeInfoPropertyNames
{
internal const string PID = "PID";
internal const string Architecture = "Architecture";
internal const string Framework = "Framework";
internal const string OS = "OS";
internal const string ProtocolVersion = "ProtocolVersion";
internal const string HostType = "HostType";
internal const string ModulePath = "ModulePath";
}

internal static class ProtocolConstants
{
internal const string Version = "1.0.0";
}
}
36 changes: 34 additions & 2 deletions src/Cli/dotnet/commands/dotnet-test/CustomEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,45 @@

namespace Microsoft.DotNet.Cli
{
internal class ErrorEventArgs : EventArgs
internal class HandshakeInfoArgs : EventArgs
{
public string ErrorMessage { get; set; }
public HandshakeInfo handshakeInfo { get; set; }
}

internal class HelpEventArgs : EventArgs
{
public CommandLineOptionMessages CommandLineOptionMessages { get; set; }
}

internal class SuccessfulTestResultEventArgs : EventArgs
{
public SuccessfulTestResultMessage SuccessfulTestResultMessage { get; set; }
}

internal class FailedTestResultEventArgs : EventArgs
{
public FailedTestResultMessage FailedTestResultMessage { get; set; }
}

internal class FileArtifactInfoEventArgs : EventArgs
{
public FileArtifactInfo FileArtifactInfo { get; set; }
}

internal class SessionEventArgs : EventArgs
{
public TestSessionEvent SessionEvent { get; set; }
}

internal class ErrorEventArgs : EventArgs
{
public string ErrorMessage { get; set; }
}

internal class TestProcessExitEventArgs : EventArgs
{
public List<string> OutputData { get; set; }
public List<string> ErrorData { get; set; }
public int ExitCode { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DotNet.Tools.Test
{
internal sealed record FileArtifactInfo(string FullPath, string DisplayName, string Description, string TestUid, string TestDisplayName, string SessionUid, string ModulePath) : IRequest;
mariam-abdulla marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DotNet.Tools.Test
{
internal sealed record HandshakeInfo(Dictionary<string, string> Properties) : IRequest, IResponse;
}
Original file line number Diff line number Diff line change
@@ -0,0 +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.

namespace Microsoft.DotNet.Tools.Test
{
internal sealed record SuccessfulTestResultMessage(string Uid, string DisplayName, string State, string Reason, string SessionUid, string ModulePath) : IRequest;

internal sealed record FailedTestResultMessage(string Uid, string DisplayName, string State, string Reason, string ErrorMessage, string ErrorStackTrace, string SessionUid, string ModulePath) : IRequest;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.DotNet.Tools.Test
{
internal sealed record TestSessionEvent(string SessionType, string SessionUid, string ModulePath) : IRequest;
}
40 changes: 40 additions & 0 deletions src/Cli/dotnet/commands/dotnet-test/IPC/ObjectFieldIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,44 @@ internal static class CommandLineOptionMessageFieldsId
internal const int IsHidden = 3;
internal const int IsBuiltIn = 4;
}

internal static class SuccessfulTestResultMessageFieldsId
{
internal const int Uid = 1;
internal const int DisplayName = 2;
internal const int State = 3;
internal const int Reason = 4;
internal const int SessionUid = 5;
internal const int ModulePath = 6;
}

internal static class FailedTestResultMessageFieldsId
{
internal const int Uid = 1;
internal const int DisplayName = 2;
internal const int State = 3;
internal const int Reason = 4;
internal const int ErrorMessage = 5;
internal const int ErrorStackTrace = 6;
internal const int SessionUid = 7;
internal const int ModulePath = 8;
}

internal static class FileArtifactInfoFieldsId
{
internal const int FullPath = 1;
internal const int DisplayName = 2;
internal const int Description = 3;
internal const int TestUid = 4;
internal const int TestDisplayName = 5;
internal const int SessionUid = 6;
internal const int ModulePath = 7;
}

internal static class TestSessionEventFieldsId
{
internal const int SessionType = 1;
internal const int SessionUid = 2;
internal const int ModulePath = 3;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,28 @@ protected static bool ReadBool(Stream stream)

protected static void WriteField(Stream stream, ushort id, string? value)
{
if (value is null)
if (IsNull(value))
{
return;
}

WriteShort(stream, id);
WriteStringSize(stream, value);
WriteString(stream, value);
WriteStringSize(stream, value!);
WriteString(stream, value!);
}

protected static void WriteField(Stream stream, string? value)
{
if (IsNull(value))
{
return;
}

WriteString(stream, value!);
}

protected static bool IsNull(string? value) => value is null;
mariam-abdulla marked this conversation as resolved.
Show resolved Hide resolved

protected static void WriteField(Stream stream, ushort id, bool value)
{
WriteShort(stream, id);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics;

namespace Microsoft.DotNet.Tools.Test
{
/*
|---FieldCount---| 2 bytes

|---File FullPath Id---| 1 (2 bytes)
|---File FullPath Size---| (4 bytes)
|---File FullPath Value---| (n bytes)

|---File DisplayName Id---| 1 (2 bytes)
|---File DisplayName Size---| (4 bytes)
|---File DisplayName Value---| (n bytes)

|---File Description Id---| 1 (2 bytes)
|---File Description Size---| (4 bytes)
|---File Description Value---| (n bytes)

|---File TestUid Id---| 1 (2 bytes)
|---File TestUid Size---| (4 bytes)
|---File TestUid Value---| (n bytes)

|---File TestDisplayName Id---| 1 (2 bytes)
|---File TestDisplayName Size---| (4 bytes)
|---File TestDisplayName Value---| (n bytes)

|---File SessionUid Id---| 1 (2 bytes)
|---File SessionUid Size---| (4 bytes)
|---File SessionUid Value---| (n bytes)

|---File ModulePath Id---| 1 (2 bytes)
|---File ModulePath Size---| (4 bytes)
|---File ModulePath Value---| (n bytes)
*/

internal sealed class FileArtifactInfoSerializer : BaseSerializer, INamedPipeSerializer
{
public int Id => 7;

public object Deserialize(Stream stream)
{
string fullPath = string.Empty;
string displayName = string.Empty;
string description = string.Empty;
string testUid = string.Empty;
string testDisplayName = string.Empty;
string sessionUid = string.Empty;
string modulePath = string.Empty;

ushort fieldCount = ReadShort(stream);

for (int i = 0; i < fieldCount; i++)
{
int fieldId = ReadShort(stream);
int fieldSize = ReadInt(stream);

switch (fieldId)
{
case FileArtifactInfoFieldsId.FullPath:
fullPath = ReadString(stream);
break;

case FileArtifactInfoFieldsId.DisplayName:
displayName = ReadString(stream);
break;

case FileArtifactInfoFieldsId.Description:
description = ReadString(stream);
break;

case FileArtifactInfoFieldsId.TestUid:
testUid = ReadString(stream);
break;

case FileArtifactInfoFieldsId.TestDisplayName:
testDisplayName = ReadString(stream);
break;

case FileArtifactInfoFieldsId.SessionUid:
sessionUid = ReadString(stream);
break;

case FileArtifactInfoFieldsId.ModulePath:
modulePath = ReadString(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 FileArtifactInfo(fullPath, displayName, description, testUid, testDisplayName, sessionUid, modulePath);
}

public void Serialize(object objectToSerialize, Stream stream)
{
Debug.Assert(stream.CanSeek, "We expect a seekable stream.");

var fileArtifactInfo = (FileArtifactInfo)objectToSerialize;

WriteShort(stream, GetFieldCount(fileArtifactInfo));

WriteField(stream, FileArtifactInfoFieldsId.FullPath, fileArtifactInfo.FullPath);
WriteField(stream, FileArtifactInfoFieldsId.DisplayName, fileArtifactInfo.DisplayName);
WriteField(stream, FileArtifactInfoFieldsId.Description, fileArtifactInfo.Description);
WriteField(stream, FileArtifactInfoFieldsId.TestUid, fileArtifactInfo.TestUid);
WriteField(stream, FileArtifactInfoFieldsId.TestDisplayName, fileArtifactInfo.TestDisplayName);
WriteField(stream, FileArtifactInfoFieldsId.SessionUid, fileArtifactInfo.SessionUid);
WriteField(stream, FileArtifactInfoFieldsId.ModulePath, fileArtifactInfo.ModulePath);
}

private static ushort GetFieldCount(FileArtifactInfo fileArtifactInfo) =>
(ushort)((IsNull(fileArtifactInfo.FullPath) ? 0 : 1) +
(IsNull(fileArtifactInfo.DisplayName) ? 0 : 1) +
(IsNull(fileArtifactInfo.Description) ? 0 : 1) +
(IsNull(fileArtifactInfo.TestUid) ? 0 : 1) +
(IsNull(fileArtifactInfo.TestDisplayName) ? 0 : 1) +
(IsNull(fileArtifactInfo.SessionUid) ? 0 : 1) +
(IsNull(fileArtifactInfo.ModulePath) ? 0 : 1));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Diagnostics;

namespace Microsoft.DotNet.Tools.Test
{
internal sealed class HandshakeInfoSerializer : BaseSerializer, INamedPipeSerializer
{
public int Id => 9;

public object Deserialize(Stream stream)
{
Dictionary<string, string> properties = new();

ushort fieldCount = ReadShort(stream);

for (int i = 0; i < fieldCount; i++)
{
properties.Add(ReadString(stream), ReadString(stream));
}

return new HandshakeInfo(properties);
}

public void Serialize(object objectToSerialize, Stream stream)
{
Debug.Assert(stream.CanSeek, "We expect a seekable stream.");

var handshakeInfo = (HandshakeInfo)objectToSerialize;

WriteShort(stream, (ushort)handshakeInfo.Properties.Count);

foreach (KeyValuePair<string, string> property in handshakeInfo.Properties)
{
WriteField(stream, property.Key);
WriteField(stream, property.Value);
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,24 @@ namespace Microsoft.DotNet.Tools.Test;
* TestHostProcessPIDRequestSerializer: 2
* CommandLineOptionMessagesSerializer: 3
* ModuleSerializer: 4
*/
* SuccessfulTestResultMessageSerializer: 5
* FailedTestResultMessageSerializer: 6
* FileArtifactInfoSerializer: 7
* TestSessionEventSerializer: 8
* HandshakeInfoSerializer: 9
*/

internal static class RegisterSerializers
{
public static void RegisterAllSerializers(this NamedPipeBase namedPipeBase)
{
namedPipeBase.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse));
namedPipeBase.RegisterSerializer(new ModuleSerializer(), typeof(Module));
namedPipeBase.RegisterSerializer(new CommandLineOptionMessagesSerializer(), typeof(CommandLineOptionMessages));
namedPipeBase.RegisterSerializer(new SuccessfulTestResultMessageSerializer(), typeof(SuccessfulTestResultMessage));
namedPipeBase.RegisterSerializer(new FailedTestResultMessageSerializer(), typeof(FailedTestResultMessage));
namedPipeBase.RegisterSerializer(new FileArtifactInfoSerializer(), typeof(FileArtifactInfo));
namedPipeBase.RegisterSerializer(new TestSessionEventSerializer(), typeof(TestSessionEvent));
namedPipeBase.RegisterSerializer(new HandshakeInfoSerializer(), typeof(HandshakeInfo));
}
}
Loading
Loading