Skip to content

Commit

Permalink
Fix deserializers for DiscoveryRequestArgs and RunRequestArgs (#2768)
Browse files Browse the repository at this point in the history
Co-authored-by: Amaury Levé <amauryleve@microsoft.com>
  • Loading branch information
mariam-abdulla and Evangelink committed Apr 29, 2024
1 parent 5dc43f4 commit 5e446fb
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 9 deletions.
16 changes: 14 additions & 2 deletions src/Platform/Microsoft.Testing.Platform/ServerMode/Json/Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ public Json(Dictionary<Type, JsonSerializer>? serializers = null, Dictionary<Typ
string runId = json.Bind<string>(jsonElement, JsonRpcStrings.RunId);
_ = Guid.TryParse(runId, out Guid result);
json.TryBind(jsonElement, out ICollection<TestNode>? testNodes, JsonRpcStrings.Tests);
json.TryArrayBind(jsonElement, out TestNode[]? testNodes, JsonRpcStrings.Tests);
json.TryBind(jsonElement, out string? graphFilter, JsonRpcStrings.Filter);
return new DiscoverRequestArgs(
Expand All @@ -564,7 +564,7 @@ public Json(Dictionary<Type, JsonSerializer>? serializers = null, Dictionary<Typ
string runId = json.Bind<string>(jsonElement, JsonRpcStrings.RunId);
_ = Guid.TryParse(runId, out Guid result);
json.TryBind(jsonElement, out ICollection<TestNode>? testNodes, JsonRpcStrings.Tests);
json.TryArrayBind(jsonElement, out TestNode[]? testNodes, JsonRpcStrings.Tests);
json.TryBind(jsonElement, out string? graphFilter, JsonRpcStrings.Filter);
return new RunRequestArgs(
Expand Down Expand Up @@ -726,6 +726,18 @@ internal bool TryBind<T>(JsonElement element, out T? value, string? property = n
return true;
}

internal bool TryArrayBind<T>(JsonElement element, out T[]? value, string? property = null)
{
if (property is not null && !element.TryGetProperty(property, out element))
{
value = default;
return false;
}

value = element.EnumerateArray().Select(x => Deserialize<T>(x)).ToArray();
return true;
}

private T Deserialize<T>(JsonElement element)
{
bool deserializerFound = _deserializers.TryGetValue(typeof(T), out JsonDeserializer? deserializer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Testing.TestInfrastructure;

using TestNode = Microsoft.Testing.Platform.Extensions.Messages.TestNode;
using TestNodeUid = Microsoft.Testing.Platform.Extensions.Messages.TestNodeUid;

namespace Microsoft.Testing.Platform.UnitTests;

Expand Down Expand Up @@ -70,19 +71,64 @@ public async Task SerializeDeserialize_Succeed(Type type)
}

static bool HasCustomDeserializeAssert(Type type) => type == typeof(TestNode);
static void CustomAssert(Type type, object instanceDeserialized, object originalObject)
}

[Arguments(typeof(DiscoverRequestArgs))]
[Arguments(typeof(RunRequestArgs))]
public void DeserializeSpecificTypes(Type type)
{
var json = CreateSerializedInstance(type);
Type? deserializer = SerializerUtilities.DeserializerTypes.SingleOrDefault(x => x == type);

if (deserializer is not null)
{
if (type == typeof(TestNode))
var actual = Deserialize(deserializer, json);
object expected = CreateInstance(type);

if (type == typeof(DiscoverRequestArgs))
{
var deserialized = (TestNode)instanceDeserialized;
var original = (TestNode)originalObject;
Assert.AreEqual(original.Uid, deserialized.Uid);
Assert.AreEqual(original.DisplayName, deserialized.DisplayName);
Assert.AreEqual(original.Properties.Single<TestFileLocationProperty>(), deserialized.Properties.Single<TestFileLocationProperty>());
AssertRequestArgs(type, (DiscoverRequestArgs)actual, (DiscoverRequestArgs)expected);
}
else if (type == typeof(RunRequestArgs))
{
AssertRequestArgs(type, (RunRequestArgs)actual, (RunRequestArgs)expected);
}
else
{
Assert.AreEqual(actual, expected);
}
}
}

private void AssertRequestArgs<TRequestArgs>(Type type, TRequestArgs actualRequest, TRequestArgs expectedRequest)
where TRequestArgs : RequestArgsBase
{
Assert.AreEqual(expectedRequest.RunId, actualRequest.RunId);
Assert.AreEqual(expectedRequest.TestNodes?.Count, actualRequest.TestNodes?.Count);

var actualTestNodes = actualRequest.TestNodes?.ToArray();
var expectedTestNodes = expectedRequest.TestNodes?.ToArray();

for (int i = 0; i < actualRequest.TestNodes?.Count; i++)
{
CustomAssert(typeof(TestNode), actualTestNodes?[i]!, expectedTestNodes?[i]!);
}

Assert.AreEqual(expectedRequest.GraphFilter, actualRequest.GraphFilter);
}

private static void CustomAssert(Type type, object instanceDeserialized, object originalObject)
{
if (type == typeof(TestNode))
{
var deserialized = (TestNode)instanceDeserialized;
var original = (TestNode)originalObject;
Assert.AreEqual(original.Uid, deserialized.Uid);
Assert.AreEqual(original.DisplayName, deserialized.DisplayName);
Assert.AreEqual(original.Properties.Single<TestFileLocationProperty>(), deserialized.Properties.Single<TestFileLocationProperty>());
}
}

internal static TestArgumentsEntry<Type> FormatSerializerTypes(TestArgumentsContext testArgumentsContext)
=> new((Type)testArgumentsContext.Arguments, ((Type)testArgumentsContext.Arguments).Name);

Expand Down Expand Up @@ -218,6 +264,26 @@ private static void AssertSerialize(Type type, string instanceSerialized)
throw new NotImplementedException($"Assertion not implemented '{type}', value to assert:\n{instanceSerialized}");
}

private static string CreateSerializedInstance(Type type)
{
return type == typeof(DiscoverRequestArgs) || type == typeof(RunRequestArgs)
? """
{
"runId":"00000000-0000-0000-0000-000000000000",
"tests":[
{
"uid":"UnitTest1.TestMethod1",
"display-name":"test1",
"location.file":"filePath",
"location.line-start":1,
"location.line-end":2
}
]
}
"""
: throw new NotImplementedException($"Serialized instance doesn't exist for '{type}'");
}

private static object CreateInstance(Type type)
{
if (type == typeof(AttachDebuggerInfoArgs))
Expand Down Expand Up @@ -323,6 +389,38 @@ private static object CreateInstance(Type type)
return new RequestMessage(1, "testing/discoverTests", null);
}

if (type == typeof(DiscoverRequestArgs))
{
return new DiscoverRequestArgs(
Guid.Empty,
new TestNode[]
{
new()
{
Uid = new TestNodeUid("UnitTest1.TestMethod1"),
DisplayName = "test1",
Properties = new PropertyBag(new TestFileLocationProperty("filePath", new LinePositionSpan(new(1, 0), new(2, 0)))),
},
},
null);
}

if (type == typeof(RunRequestArgs))
{
return new RunRequestArgs(
Guid.Empty,
new TestNode[]
{
new()
{
Uid = new TestNodeUid("UnitTest1.TestMethod1"),
DisplayName = "test1",
Properties = new PropertyBag(new TestFileLocationProperty("filePath", new LinePositionSpan(new(1, 0), new(2, 0)))),
},
},
null);
}

// Last resort, try to create an instance of the type
return type == typeof(object)
? new object()
Expand Down Expand Up @@ -396,6 +494,24 @@ private object Deserialize(Type type, string instanceSerialized)
#endif
}

if (type == typeof(DiscoverRequestArgs))
{
#if NETCOREAPP
return _formatter.Deserialize<DiscoverRequestArgs>(instanceSerialized.AsMemory());
#else
return _formatter.Deserialize<DiscoverRequestArgs>(instanceSerialized);
#endif
}

if (type == typeof(RunRequestArgs))
{
#if NETCOREAPP
return _formatter.Deserialize<RunRequestArgs>(instanceSerialized.AsMemory());
#else
return _formatter.Deserialize<RunRequestArgs>(instanceSerialized);
#endif
}

if (type == typeof(ServerCapabilities))
{
#if NETCOREAPP
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLo
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLoggerTests.Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(Microsoft.Testing.Platform.Logging.LogLevel, Microsoft.Testing.Platform.Logging.LogLevel) [6]
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLoggerTests.Write_IfMalformedUTF8_ShouldNotCrash()
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.CanDeserializeTaskResponse()
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.DeserializeSpecificTypes(System.Type) (type: typeof(Microsoft.Testing.Platform.ServerMode.DiscoverRequestArgs))
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.DeserializeSpecificTypes(System.Type) (type: typeof(Microsoft.Testing.Platform.ServerMode.RunRequestArgs))
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (Artifact)
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (AttachDebuggerInfoArgs)
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (CancelRequestArgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLo
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLoggerTests.Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(Microsoft.Testing.Platform.Logging.LogLevel, Microsoft.Testing.Platform.Logging.LogLevel) [6]
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FileLoggerTests.Write_IfMalformedUTF8_ShouldNotCrash()
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.CanDeserializeTaskResponse()
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.DeserializeSpecificTypes(System.Type) (type: typeof(Microsoft.Testing.Platform.ServerMode.DiscoverRequestArgs))
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.DeserializeSpecificTypes(System.Type) (type: typeof(Microsoft.Testing.Platform.ServerMode.RunRequestArgs))
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (Artifact)
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (AttachDebuggerInfoArgs)
Microsoft.Testing.Platform.UnitTests.Microsoft.Testing.Platform.UnitTests.FormatterUtilitiesTests.SerializeDeserialize_Succeed(System.Type) (CancelRequestArgs)
Expand Down

0 comments on commit 5e446fb

Please sign in to comment.