From 391116cd0ccd95b5796a6a9da975aa7f12708226 Mon Sep 17 00:00:00 2001 From: Alexander Alexeev Date: Tue, 19 Oct 2021 00:18:25 +0300 Subject: [PATCH] Fix concurrent issues in DataSerializationHelper (#998) * Fix concurrent issues in DataSerializationHelper Co-authored-by: Alexander Alexeev Co-authored-by: Medeni Baykal <433724+Haplois@users.noreply.github.com> --- .../Helpers/DataSerializationHelper.cs | 41 ++++++------------- .../Automation.CLI/CLITestBase.common.cs | 2 +- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/Adapter/MSTest.CoreAdapter/Helpers/DataSerializationHelper.cs b/src/Adapter/MSTest.CoreAdapter/Helpers/DataSerializationHelper.cs index 3c99e68b28..9e3ad9cda7 100644 --- a/src/Adapter/MSTest.CoreAdapter/Helpers/DataSerializationHelper.cs +++ b/src/Adapter/MSTest.CoreAdapter/Helpers/DataSerializationHelper.cs @@ -4,16 +4,14 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers { using System; - using System.Collections.Generic; + using System.Collections.Concurrent; using System.IO; - using System.Linq; - using System.Reflection; using System.Runtime.Serialization.Json; using System.Text; internal static class DataSerializationHelper { - private static readonly Dictionary SerializerCache = new Dictionary(); + private static readonly ConcurrentDictionary SerializerCache = new ConcurrentDictionary(); private static readonly DataContractJsonSerializerSettings SerializerSettings = new DataContractJsonSerializerSettings() { UseSimpleDictionaryFormat = true, @@ -35,12 +33,10 @@ public static string[] Serialize(object[] data) } var serializedData = new string[data.Length * 2]; - for (int i = 0; i < data.Length; i++) { var typeIndex = i * 2; var dataIndex = typeIndex + 1; - if (data[i] == null) { serializedData[typeIndex] = null; @@ -86,16 +82,16 @@ public static object[] Deserialize(string[] serializedData) for (int i = 0; i < length; i++) { var typeIndex = i * 2; - var typeName = serializedData[typeIndex]; + var assemblyQualifiedName = serializedData[typeIndex]; var serializedValue = serializedData[typeIndex + 1]; - if (serializedValue == null || typeName == null) + if (serializedValue == null || assemblyQualifiedName == null) { data[i] = null; continue; } - var serializer = GetSerializer(typeName); + var serializer = GetSerializer(assemblyQualifiedName); var serialzedDataBytes = Encoding.UTF8.GetBytes(serializedValue); using (var memoryStream = new MemoryStream(serialzedDataBytes)) @@ -107,31 +103,18 @@ public static object[] Deserialize(string[] serializedData) return data; } - private static DataContractJsonSerializer GetSerializer(string typeName) + private static DataContractJsonSerializer GetSerializer(string assemblyQualifiedName) { - var serializer = SerializerCache.SingleOrDefault(i => i.Key.FullName == typeName); - if (serializer.Value != null) - { - return serializer.Value; - } - - var type = Type.GetType(typeName); - if (type != null) - { - return GetSerializer(type); - } - - return GetSerializer(typeof(object)); + return SerializerCache.GetOrAdd( + assemblyQualifiedName, + _ => new DataContractJsonSerializer(Type.GetType(assemblyQualifiedName) ?? typeof(object), SerializerSettings)); } private static DataContractJsonSerializer GetSerializer(Type type) { - if (SerializerCache.ContainsKey(type)) - { - return SerializerCache[type]; - } - - return SerializerCache[type] = new DataContractJsonSerializer(type, SerializerSettings); + return SerializerCache.GetOrAdd( + type.AssemblyQualifiedName, + _ => new DataContractJsonSerializer(type, SerializerSettings)); } } } diff --git a/test/E2ETests/Automation.CLI/CLITestBase.common.cs b/test/E2ETests/Automation.CLI/CLITestBase.common.cs index 3d60a1620d..213df2a3d0 100644 --- a/test/E2ETests/Automation.CLI/CLITestBase.common.cs +++ b/test/E2ETests/Automation.CLI/CLITestBase.common.cs @@ -17,7 +17,7 @@ public partial class CLITestBase private const string PackagesFolder = "packages"; // This value is automatically updated by "build.ps1" script. - private const string TestPlatformCLIPackage = @"Microsoft.TestPlatform\17.0.0-preview-20210730-03"; + private const string TestPlatformCLIPackage = @"Microsoft.TestPlatform\17.0.0-release-20210923-02"; private const string VstestConsoleRelativePath = @"tools\net451\Common7\IDE\Extensions\TestPlatform\vstest.console.exe"; ///