From 86e329afeb55d26a1e1399b2b70c604feb98fd43 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 09:22:08 +0100 Subject: [PATCH 01/10] add test run serialization feature --- .../TestPlatform.Playground.csproj | 2 +- .../ExtensionDecoratorFactory.cs | 23 +++ .../SerializeTestRunDecorator.cs | 137 +++++++++++++++++ .../Utilities/LazyExtension.cs | 15 +- .../Resources/Resources.Designer.cs | 18 ++- .../Resources/Resources.resx | 3 + .../Resources/xlf/Resources.cs.xlf | 5 + .../Resources/xlf/Resources.de.xlf | 5 + .../Resources/xlf/Resources.es.xlf | 5 + .../Resources/xlf/Resources.fr.xlf | 5 + .../Resources/xlf/Resources.it.xlf | 5 + .../Resources/xlf/Resources.ja.xlf | 5 + .../Resources/xlf/Resources.ko.xlf | 5 + .../Resources/xlf/Resources.pl.xlf | 5 + .../Resources/xlf/Resources.pt-BR.xlf | 5 + .../Resources/xlf/Resources.ru.xlf | 5 + .../Resources/xlf/Resources.tr.xlf | 5 + .../Resources/xlf/Resources.xlf | 5 + .../Resources/xlf/Resources.zh-Hans.xlf | 5 + .../Resources/xlf/Resources.zh-Hant.xlf | 5 + .../FeatureFlag/FeatureFlag.cs | 3 + .../Properties/AssemblyInfo.cs | 1 + .../Execution/BaseRunTests.cs | 8 +- .../RunSettings/RunConfiguration.cs | 6 +- .../CodeCoverageDataAttachmentsHandler.cs | 25 ++- .../SerializeTestRunTests.cs | 114 ++++++++++++++ .../ExtensionDecoratorTests.cs | 142 ++++++++++++++++++ ...CodeCoverageDataAttachmentsHandlerTests.cs | 24 +++ .../SerializeTestRunTestProject.csproj | 28 ++++ .../SerializeTestRunTestProject/UnitTest1.cs | 55 +++++++ test/TestAssets/TestAssets.sln | 16 +- 31 files changed, 678 insertions(+), 12 deletions(-) create mode 100644 src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs create mode 100644 src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs create mode 100644 test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs create mode 100644 test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs create mode 100644 test/TestAssets/SerializeTestRunTestProject/SerializeTestRunTestProject.csproj create mode 100644 test/TestAssets/SerializeTestRunTestProject/UnitTest1.cs diff --git a/playground/TestPlatform.Playground/TestPlatform.Playground.csproj b/playground/TestPlatform.Playground/TestPlatform.Playground.csproj index ed6ad67876..ae2d55497d 100644 --- a/playground/TestPlatform.Playground/TestPlatform.Playground.csproj +++ b/playground/TestPlatform.Playground/TestPlatform.Playground.csproj @@ -62,7 +62,7 @@ - + diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs new file mode 100644 index 0000000000..3478685ecc --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs @@ -0,0 +1,23 @@ +// 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.VisualStudio.TestPlatform.ObjectModel.Adapter; +using Microsoft.VisualStudio.TestPlatform.Utilities; + +namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; +internal class ExtensionDecoratorFactory +{ + private readonly IFeatureFlag _featureFlag; + + public ExtensionDecoratorFactory(IFeatureFlag featureFlag) + { + _featureFlag = featureFlag; + } + + public ITestExecutor Decorate(ITestExecutor originalTestExecutor) + { + return _featureFlag.IsSet(FeatureFlag.DISABLE_SERIALIZETESTRUN_DECORATOR) + ? originalTestExecutor + : new SerializeTestRunDecorator(originalTestExecutor); + } +} diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs new file mode 100644 index 0000000000..01e91737a1 --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs @@ -0,0 +1,137 @@ +// 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; +using System.Collections.Generic; +using System.Threading; +using System.Xml.Linq; + +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + +namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; + +internal class SerializeTestRunDecorator : ITestExecutor, ITestExecutor2, IDisposable +{ + private readonly SemaphoreSlim _runSequentialEvent = new(1); + + public ITestExecutor OriginalTestExecutor { get; private set; } + + public SerializeTestRunDecorator(ITestExecutor originalTestExecutor) + { + OriginalTestExecutor = originalTestExecutor; + } + + public void RunTests(IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) + { + if (IsSerializeTestRunEnabled(runContext)) + { + EqtTrace.Info($"SerializeTestRunDecorator: Test cases will run sequentially"); + if (tests is null) + { + return; + } + + foreach (TestCase testToRun in tests) + { + _runSequentialEvent.Wait(); + OriginalTestExecutor.RunTests(new List { testToRun }, runContext, new SerializeTestRunDecoratorFrameworkHandle(frameworkHandle!, _runSequentialEvent)); + } + } + else + { + OriginalTestExecutor.RunTests(tests, runContext, frameworkHandle); + } + } + + public void RunTests(IEnumerable? sources, IRunContext? runContext, IFrameworkHandle? frameworkHandle) + { + if (IsSerializeTestRunEnabled(runContext)) + { + EqtTrace.Error(Resources.Resources.SerializeTestRunInvalidScenario); + frameworkHandle?.SendMessage(TestMessageLevel.Error, Resources.Resources.SerializeTestRunInvalidScenario); + } + else + { + OriginalTestExecutor.RunTests(sources, runContext, frameworkHandle); + } + } + + public bool ShouldAttachToTestHost(IEnumerable? sources, IRunContext runContext) + { + if (OriginalTestExecutor is ITestExecutor2 executor) + { + return executor.ShouldAttachToTestHost(sources, runContext); + } + + // If the adapter doesn't implement the new test executor interface we should attach to + // the default test host by default to preserve old behavior. + return true; + } + + public bool ShouldAttachToTestHost(IEnumerable? tests, IRunContext runContext) + { + if (OriginalTestExecutor is ITestExecutor2 executor) + { + return executor.ShouldAttachToTestHost(tests, runContext); + } + + // If the adapter doesn't implement the new test executor interface we should attach to + // the default test host by default to preserve old behavior. + return true; + } + + public void Cancel() + => OriginalTestExecutor.Cancel(); + + private static bool IsSerializeTestRunEnabled(IRunContext? runContext) + { + if (runContext is null || runContext.RunSettings is null || runContext.RunSettings.SettingsXml is null) + { + return false; + } + + XElement runSettings = XElement.Parse(runContext.RunSettings.SettingsXml); + XElement? serializeTestRun = runSettings.Element("RunConfiguration")?.Element("SerializeTestRun"); + return serializeTestRun is not null && bool.TryParse(serializeTestRun.Value, out bool enabled) && enabled; + } + + public void Dispose() + => _runSequentialEvent.Dispose(); +} + +internal class SerializeTestRunDecoratorFrameworkHandle : IFrameworkHandle +{ + private readonly IFrameworkHandle _frameworkHandle; + private readonly SemaphoreSlim _testEnd; + + public SerializeTestRunDecoratorFrameworkHandle(IFrameworkHandle frameworkHandle, SemaphoreSlim testEnd) + { + _frameworkHandle = frameworkHandle; + _testEnd = testEnd; + } + + public bool EnableShutdownAfterTestRun { get => _frameworkHandle.EnableShutdownAfterTestRun; set => _frameworkHandle.EnableShutdownAfterTestRun = value; } + + public int LaunchProcessWithDebuggerAttached(string filePath, string? workingDirectory, string? arguments, IDictionary? environmentVariables) + => _frameworkHandle.LaunchProcessWithDebuggerAttached(filePath, workingDirectory, arguments, environmentVariables); + + public void RecordAttachments(IList attachmentSets) + => _frameworkHandle.RecordAttachments(attachmentSets); + + public void RecordEnd(TestCase testCase, TestOutcome outcome) + { + _frameworkHandle.RecordEnd(testCase, outcome); + _testEnd.Release(); + } + + public void RecordResult(TestResult testResult) + => _frameworkHandle.RecordResult(testResult); + + public void RecordStart(TestCase testCase) + => _frameworkHandle.RecordStart(testCase); + + public void SendMessage(TestMessageLevel testMessageLevel, string message) + => _frameworkHandle.SendMessage(testMessageLevel, message); +} diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs index 657920b9ed..8430e4493d 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs @@ -4,6 +4,10 @@ using System; using System.Linq; +using Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; +using Microsoft.VisualStudio.TestPlatform.Utilities; + namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities; /// @@ -16,6 +20,7 @@ public class LazyExtension private static readonly object Synclock = new(); private readonly Type? _metadataType; private readonly Func? _extensionCreator; + private readonly ExtensionDecoratorFactory _extensionDecoratorFactory = new(FeatureFlag.Instance); private TExtension? _extension; private TMetadata? _metadata; @@ -96,7 +101,15 @@ public TExtension Value TPDebug.Assert(TestPluginInfo.AssemblyQualifiedName is not null, "TestPluginInfo.AssemblyQualifiedName is null"); var pluginType = TestPluginManager.GetTestExtensionType(TestPluginInfo.AssemblyQualifiedName); TPDebug.Assert(pluginType is not null, "pluginType is null"); - _extension = TestPluginManager.CreateTestExtension(pluginType); + + var extension = TestPluginManager.CreateTestExtension(pluginType); + + if (typeof(ITestExecutor).IsAssignableFrom(typeof(TExtension))) + { + extension = (TExtension)_extensionDecoratorFactory.Decorate((ITestExecutor)extension!); + } + + _extension = extension; } } } diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs index d79a66d5ea..0e23a91950 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs @@ -10,9 +10,8 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Resources { using System; - using System.Reflection; - - + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -20,7 +19,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -40,7 +39,7 @@ internal Resources() { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.VisualStudio.TestPlatform.Common.Resources.Resources", typeof(Resources).GetTypeInfo().Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.VisualStudio.TestPlatform.Common.Resources.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; @@ -331,6 +330,15 @@ internal static string RunSettingsParseError { } } + /// + /// Looks up a localized string similar to <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run. + /// + internal static string SerializeTestRunInvalidScenario { + get { + return ResourceManager.GetString("SerializeTestRunInvalidScenario", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid settings node specified. The name property of the settings node must be non-empty.. /// diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx index a1dddd4bde..33ad0caadd 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx @@ -207,6 +207,9 @@ An error occurred while loading the run settings. Error: {0} + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + Invalid settings node specified. The name property of the settings node must be non-empty. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf index 6e90ce0ce6..860e3981ef 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf @@ -192,6 +192,11 @@ Trasování zásobníku: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf index 4ad0e12965..93878d2c73 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf @@ -192,6 +192,11 @@ Stapelüberwachung: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf index 672a9bfa70..794589b895 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf @@ -192,6 +192,11 @@ Seguimiento de la pila: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf index 8c3a5097e2..a07ff527d9 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf @@ -192,6 +192,11 @@ Arborescence des appels de procédure : + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf index 6ca503bad2..d763b314ec 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf @@ -192,6 +192,11 @@ Analisi dello stack: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf index 74c34de4c4..8dc012574c 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf @@ -192,6 +192,11 @@ スタック トレース: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf index 7e6a2db159..3f8bd3856d 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf @@ -192,6 +192,11 @@ 스택 추적: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf index c1ba20ccc6..0bc6b210af 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf @@ -192,6 +192,11 @@ Ślad stosu: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf index 48c5126257..5b1a041bcb 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf @@ -192,6 +192,11 @@ Rastreamento de pilha: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf index c8732c97b2..4c8f6ee223 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf @@ -192,6 +192,11 @@ Трассировка стека: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf index a030305684..784a33e2dc 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf @@ -192,6 +192,11 @@ Yığın izleme: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf index 21297f7741..477388ca3b 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf @@ -171,6 +171,11 @@ Stack trace: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf index 646975d4dc..4dbfec8ec2 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf @@ -192,6 +192,11 @@ 堆栈跟踪: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf index dc6339b00c..ddb2390cd0 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf @@ -192,6 +192,11 @@ 堆疊追蹤: + + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs b/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs index 7ec5505490..c70581f59f 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs @@ -54,6 +54,9 @@ private FeatureFlag() { } // even though we are blocking additional threads becuase we don't have to wait for ThreadPool to start more threads. public const string DISABLE_THREADPOOL_SIZE_INCREASE = VSTEST_ + nameof(DISABLE_THREADPOOL_SIZE_INCREASE); + // Disable the SerializeTestRunDecorator + public const string DISABLE_SERIALIZETESTRUN_DECORATOR = VSTEST_ + nameof(DISABLE_SERIALIZETESTRUN_DECORATOR); + [Obsolete("Only use this in tests.")] internal static void Reset() { diff --git a/src/Microsoft.TestPlatform.CoreUtilities/Properties/AssemblyInfo.cs b/src/Microsoft.TestPlatform.CoreUtilities/Properties/AssemblyInfo.cs index 0c5393875c..cba9118b37 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/Properties/AssemblyInfo.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/Properties/AssemblyInfo.cs @@ -33,6 +33,7 @@ [assembly: InternalsVisibleTo("vstest.console.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Extensions.BlameDataCollector, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.TestPlatform.Extensions.BlameDataCollector.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] +[assembly: InternalsVisibleTo("Microsoft.TestPlatform.Common.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("d472046e-ed17-4750-a2a3-29935b5215f6")] diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs index b6af308c46..155080fa8e 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs @@ -12,6 +12,7 @@ using System.Reflection; using System.Threading.Tasks; +using Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework; using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework.Utilities; using Microsoft.VisualStudio.TestPlatform.Common.Interfaces; @@ -492,8 +493,13 @@ private bool RunTestInternalWithExecutors(IEnumerable> execut if (!CrossPlatEngine.Constants.DefaultAdapters.Contains(executor.Metadata.ExtensionUri, StringComparer.OrdinalIgnoreCase)) { - var executorLocation = executor.Value.GetType().GetTypeInfo().Assembly.GetAssemblyLocation(); + // If real executor is wrapped by a decorator we get the real decorated type + TypeInfo executorTypeInfo = + (executor.Value is SerializeTestRunDecorator serializeTestRunDecorator) ? + serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() : + executor.Value.GetType().GetTypeInfo(); + var executorLocation = executorTypeInfo.Assembly.GetAssemblyLocation(); executorsFromDeprecatedLocations |= Path.GetDirectoryName(executorLocation)!.Equals(CrossPlatEngine.Constants.DefaultAdapterLocation); } diff --git a/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs b/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs index 65ab1a1ab4..b7be15b059 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/RunSettings/RunConfiguration.cs @@ -901,7 +901,11 @@ public static RunConfiguration FromXml(XmlReader reader) } runConfiguration.TreatNoTestsAsError = treatNoTestsAsError; break; - + // Configuration used but not exposed to the public to avoid the Warning inside the log + case "SerializeTestRun": + case "EnvironmentVariables": + reader.Skip(); + break; default: // Ignore a runsettings element that we don't understand. It could occur in the case // the test runner is of a newer version, but the test host is of an earlier version. diff --git a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs index be25c77976..baf5d30690 100644 --- a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs +++ b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs @@ -49,6 +49,12 @@ public async Task> ProcessAttachmentSetsAsync(XmlElem if (attachments?.Any() != true) return new Collection(); + // Merging per test code coverage is not supported + if (PerTestCoverageEnabled(configurationElement)) + { + return attachments; + } + var coverageReportFilePaths = new List(); var coverageOtherFilePaths = new List(); @@ -90,6 +96,20 @@ public async Task> ProcessAttachmentSetsAsync(XmlElem } return attachments; + + static bool PerTestCoverageEnabled(XmlElement? configurationElement) + { + XmlNodeList? xmlNodeList = configurationElement?.GetElementsByTagName("PerTestCodeCoverage"); + if (xmlNodeList?.Count == 1) + { + if (bool.TryParse(xmlNodeList[0]?.InnerText, out bool enabled)) + { + return enabled; + } + } + + return false; + } } private static async Task?> MergeCodeCoverageFilesAsync(IList files, IProgress progressReporter, CancellationToken cancellationToken) @@ -122,12 +142,13 @@ public async Task> ProcessAttachmentSetsAsync(XmlElem private static async Task?> MergeCodeCoverageFilesAsync(IList files, CancellationToken cancellationToken) { - TPDebug.Assert(s_mergeOperationEnumValues != null); - cancellationToken.ThrowIfCancellationRequested(); // Invoke methods LoadCodeCoverageAssembly(); + + TPDebug.Assert(s_mergeOperationEnumValues != null); + var task = (Task)s_mergeMethodInfo.Invoke(s_classInstance, new object[] { files[0], files, s_mergeOperationEnumValues.GetValue(0)!, true, cancellationToken })!; await task.ConfigureAwait(false); diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs new file mode 100644 index 0000000000..86d59b6205 --- /dev/null +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs @@ -0,0 +1,114 @@ +// 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; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text; + +using Microsoft.TestPlatform.VsTestConsole.TranslationLayer.Interfaces; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests; + +[TestClass] +// We need to dogfood the package built in this repo *-dev and we pack tha tp only on windows +[TestCategory("Windows-Review")] +public class SerializeTestRunTests : AcceptanceTestBase +{ + private IVsTestConsoleWrapper? _vstestConsoleWrapper; + private RunEventHandler? _runEventHandler; + private DiscoveryEventHandler? _discoveryEventHandler; + private DiscoveryEventHandler2? _discoveryEventHandler2; + private readonly string _runsettings = @" + + + true + + +"; + + [MemberNotNull(nameof(_vstestConsoleWrapper), nameof(_runEventHandler), nameof(_discoveryEventHandler), nameof(_discoveryEventHandler2))] + private void Setup(Dictionary? environmentVariables = null) + { + _vstestConsoleWrapper = GetVsTestConsoleWrapper(environmentVariables); + _discoveryEventHandler = new DiscoveryEventHandler(); + _discoveryEventHandler2 = new DiscoveryEventHandler2(); + _runEventHandler = new RunEventHandler(); + } + + [TestCleanup] + public void Cleanup() + { + _vstestConsoleWrapper?.EndSession(); + } + + [TestMethod] + [NetCoreTargetFrameworkDataSource] + [NetFullTargetFrameworkDataSource] + public void DiscoverTestsAndRunTestsSequentially(RunnerInfo runnerInfo) + { + // Arrange + SetTestEnvironment(_testEnvironment, runnerInfo); + Setup(); + + // Act + var testDll = GetAssetFullPath("SerializeTestRunTestProject.dll"); + _vstestConsoleWrapper.DiscoverTests(new string[] { testDll }, GetDefaultRunSettings(), _discoveryEventHandler); + _vstestConsoleWrapper.RunTests(_discoveryEventHandler.DiscoveredTestCases, _runsettings, _runEventHandler); + _runEventHandler.EnsureSuccess(); + + // Assert + Assert.AreEqual(10, _discoveryEventHandler.DiscoveredTestCases.Count); + int failedTests = _runEventHandler.TestResults.Count(x => x.Outcome == TestOutcome.Failed); + Assert.IsFalse(failedTests > 0, $"Number of failed tests {failedTests}"); + } + + [TestMethod] + [NetCoreTargetFrameworkDataSource] + [NetFullTargetFrameworkDataSource] + public void DiscoverTestsAndRunTestsSequentially_DisabledByFeatureFlag(RunnerInfo runnerInfo) + { + // Arrange + SetTestEnvironment(_testEnvironment, runnerInfo); + Dictionary? environmentVariables = new() { { "VSTEST_DISABLE_SERIALIZETESTRUN_DECORATOR", "1" } }; + Setup(environmentVariables); + + // Act + var testDll = GetAssetFullPath("SerializeTestRunTestProject.dll"); + _vstestConsoleWrapper.DiscoverTests(new string[] { testDll }, GetDefaultRunSettings(), _discoveryEventHandler); + _vstestConsoleWrapper.RunTests(_discoveryEventHandler.DiscoveredTestCases, _runsettings, _runEventHandler); + _runEventHandler.EnsureSuccess(); + + // Assert + Assert.AreEqual(10, _discoveryEventHandler.DiscoveredTestCases.Count); + int failedTests = _runEventHandler.TestResults.Count(x => x.Outcome == TestOutcome.Failed); + Assert.IsTrue(failedTests > 0, $"Number of failed tests {failedTests}"); + } + + [TestMethod] + [NetCoreTargetFrameworkDataSource] + [NetFullTargetFrameworkDataSource] + public void DiscoverTestsAndRunTestsSequentially_IsNotSupportedForSources(RunnerInfo runnerInfo) + { + // Arrange + SetTestEnvironment(_testEnvironment, runnerInfo); + Setup(); + + // Act + var testDll = GetAssetFullPath("SerializeTestRunTestProject.dll"); + _vstestConsoleWrapper.RunTests(new string[] { testDll }, _runsettings, _runEventHandler); + _ = Assert.ThrowsException(_runEventHandler.EnsureSuccess); + + StringBuilder builder = new(); + foreach (string? error in _runEventHandler.Errors) + { + builder.AppendLine(error); + } + + Assert.IsTrue(_runEventHandler.Errors.Count > 0); + Assert.IsTrue(_runEventHandler.Errors.Contains(VisualStudio.TestPlatform.Common.Resources.Resources.SerializeTestRunInvalidScenario), $"Error messages\n:{builder}"); + } +} diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs new file mode 100644 index 0000000000..917eea0098 --- /dev/null +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs @@ -0,0 +1,142 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +using Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; +using Microsoft.VisualStudio.TestPlatform.Common.Resources; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; +using Microsoft.VisualStudio.TestPlatform.Utilities; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Moq; + +namespace Microsoft.TestPlatform.Common.UnitTests.ExtensionFramework; + +[TestClass] +public class ExtensionDecoratorTests +{ + private readonly Mock _featureFlagMock = new(); + private readonly Mock _testExecutorMock = new(); + private readonly Mock _contextMock = new(); + private readonly Mock _frameworkWorkHandleMock = new(); + private readonly Mock _settingsMock = new(); + private readonly string _runsettings = @" + + + true + + "; + + [TestMethod] + public void ExtensionDecoratorFactory_DisabledByFlag() + { + // Arrange + _featureFlagMock.Setup(x => x.IsSet(FeatureFlag.DISABLE_SERIALIZETESTRUN_DECORATOR)).Returns(true); + + // Run test and assert + ExtensionDecoratorFactory extensionDecoratorFactory = new(_featureFlagMock.Object); + Mock featureFlagMock = new(); + Assert.AreEqual(featureFlagMock.Object, extensionDecoratorFactory.Decorate(featureFlagMock.Object)); + } + + [TestMethod] + public void SerializeTestRunDecorator_ShouldSerializeTests() + { + // Arrange + List testCases = new(); + for (int i = 0; i < 50; i++) + { + testCases.Add(new TestCase() { Id = Guid.NewGuid() }); + } + + long currentCount = 0; + List testCasesRan = new(); + _settingsMock.Setup(x => x.SettingsXml).Returns(_runsettings); + _contextMock.Setup(x => x.RunSettings).Returns(_settingsMock.Object); + _testExecutorMock.Setup(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny())) + .Callback((IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => + { + Assert.AreEqual(0, Interlocked.Read(ref currentCount)); + currentCount = Interlocked.Increment(ref currentCount); + TestCase tc = tests!.First(); + Task.Run(() => + { + Thread.Sleep(100); + currentCount = Interlocked.Decrement(ref currentCount); + frameworkHandle!.RecordEnd(tc, TestOutcome.Passed); + }); + testCasesRan.Add(tc); + }); + + // Run test + SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); + + // Assert + Assert.AreEqual(0, testCases.Except(testCasesRan).Count()); + } + + [TestMethod] + public void SerializeTestRunDecorator_DoesNotSupportSources() + { + // Arrange + _settingsMock.Setup(x => x.SettingsXml).Returns(_runsettings); + _contextMock.Setup(x => x.RunSettings).Returns(_settingsMock.Object); + + // Run test + SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + serializeTestRunDecorator.RunTests(new List() { "samplesource.dll" }, _contextMock.Object, _frameworkWorkHandleMock.Object); + + // Assert + _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Never()); + _frameworkWorkHandleMock.Verify(x => x.SendMessage(TestMessageLevel.Error, Resources.SerializeTestRunInvalidScenario), Times.Once()); + } + + + [TestMethod] + [DataRow("FaLsE", false)] + [DataRow("false", false)] + [DataRow("FALSE", false)] + [DataRow(null, true)] + public void SerializeTestRunDecorator_Disabled(string falseValue, bool nullRunSettings) + { + // Arrange + string runsettings = $@" + + + {falseValue} + + "; + + List testCases = new(); + for (int i = 0; i < 50; i++) + { + testCases.Add(new TestCase() { Id = Guid.NewGuid() }); + } + + string[] sourcesName = new string[] { "testSource.dll" }; + + _settingsMock.Setup(x => x.SettingsXml).Returns(nullRunSettings ? null : runsettings); + _contextMock.Setup(x => x.RunSettings).Returns(_settingsMock.Object); + _testExecutorMock.Setup(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny())) + .Callback((IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => Assert.AreEqual(testCases, tests)); + _testExecutorMock.Setup(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny())) + .Callback((IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => Assert.AreEqual(sourcesName, tests)); + + // Run test + SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); + serializeTestRunDecorator.RunTests(sourcesName, _contextMock.Object, _frameworkWorkHandleMock.Object); + + // Assert + _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Once()); + _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Once()); + } +} diff --git a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs index ba1a76432f..61c3e5b8f3 100644 --- a/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.Utilities.UnitTests/CodeCoverageDataAttachmentsHandlerTests.cs @@ -14,6 +14,7 @@ using System.Xml; using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -25,6 +26,7 @@ namespace Microsoft.TestPlatform.Utilities.UnitTests; public class CodeCoverageDataAttachmentsHandlerTests { private readonly Mock> _mockProgressReporter; + private readonly Mock _messageLogger; private readonly XmlElement _configurationElement; private readonly CodeCoverageDataAttachmentsHandler _coverageDataAttachmentsHandler; private readonly string _filePrefix; @@ -39,6 +41,7 @@ public CodeCoverageDataAttachmentsHandlerTests() doc.LoadXml(""); _configurationElement = doc.DocumentElement!; _mockProgressReporter = new Mock>(); + _messageLogger = new Mock(); _coverageDataAttachmentsHandler = new CodeCoverageDataAttachmentsHandler(); #if NETFRAMEWORK _filePrefix = "file:///"; @@ -194,4 +197,25 @@ public async Task HandleDataCollectionAttachmentSetsShouldThrowIfCancellationReq _mockProgressReporter.Verify(p => p.Report(It.IsAny()), Times.Never); } + + [TestMethod] + public async Task MergingPerTestCodeCoverageIsNotSupportedAndShoulReturnInputs() + { + string file1Path = Path.Combine(TestFilesDirectory, "fullcovered.cobertura.xml"); + var attachmentSet = new AttachmentSet(new Uri("datacollector://microsoft/CodeCoverage/2.0"), string.Empty); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri(file1Path), "coverage")); + attachmentSet.Attachments.Add(new UriDataAttachment(new Uri(file1Path), "coverage")); + + var attachment = new Collection { attachmentSet }; + + var doc = new XmlDocument(); + doc.LoadXml("TrUe"); + ICollection resultAttachmentSets = await + _coverageDataAttachmentsHandler.ProcessAttachmentSetsAsync(doc.DocumentElement!, attachment, _mockProgressReporter.Object, _messageLogger.Object, CancellationToken.None); + + Assert.IsNotNull(resultAttachmentSets); + Assert.IsTrue(resultAttachmentSets.Count == 1); + Assert.IsTrue(resultAttachmentSets.First().Attachments.Count == 2); + Assert.AreEqual("datacollector://microsoft/CodeCoverage/2.0", resultAttachmentSets.First().Uri.AbsoluteUri); + } } diff --git a/test/TestAssets/SerializeTestRunTestProject/SerializeTestRunTestProject.csproj b/test/TestAssets/SerializeTestRunTestProject/SerializeTestRunTestProject.csproj new file mode 100644 index 0000000000..cecdee1e0c --- /dev/null +++ b/test/TestAssets/SerializeTestRunTestProject/SerializeTestRunTestProject.csproj @@ -0,0 +1,28 @@ + + + + + + $(NetFrameworkMinimum);$(NetCoreAppMinimum) + netcoreapp3.1 + false + + + + + $(MSTestFrameworkVersion) + + + $(MSTestAdapterVersion) + + + $(NETTestSdkVersion) + + + + + + + + + diff --git a/test/TestAssets/SerializeTestRunTestProject/UnitTest1.cs b/test/TestAssets/SerializeTestRunTestProject/UnitTest1.cs new file mode 100644 index 0000000000..475ade64ee --- /dev/null +++ b/test/TestAssets/SerializeTestRunTestProject/UnitTest1.cs @@ -0,0 +1,55 @@ +// 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.Threading; + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +// Parallelize the execution +[assembly: Parallelize(Workers = 0, Scope = ExecutionScope.MethodLevel)] + +namespace SerializeTestRunTestProject +{ + [TestClass] + public class UnitTest1 + { + private static readonly object ObjectToAcquire = new object(); + + private static void AcquireAndReleaseLock() + { + Assert.IsTrue(Monitor.TryEnter(ObjectToAcquire)); + Thread.Sleep(100); + Monitor.Exit(ObjectToAcquire); + } + + [TestMethod] + public void TestMethod1() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod2() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod3() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod4() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod5() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod6() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod7() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod8() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod9() => AcquireAndReleaseLock(); + + [TestMethod] + public void TestMethod10() => AcquireAndReleaseLock(); + } +} diff --git a/test/TestAssets/TestAssets.sln b/test/TestAssets/TestAssets.sln index 9d6c2fd82f..8c90af525c 100644 --- a/test/TestAssets/TestAssets.sln +++ b/test/TestAssets/TestAssets.sln @@ -124,7 +124,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tools", "Tools\Tools.csproj EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Perfy.TestAdapter", "performance\Perfy.TestAdapter\Perfy.TestAdapter.csproj", "{71BF7EC9-7BEE-4038-8F4E-87032FA4E995}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RecursiveResourceLookupCrash", "RecursiveResourceLookupCrash\RecursiveResourceLookupCrash.csproj", "{9B5BDF7D-5816-47C6-8CFD-E45B152CA35F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RecursiveResourceLookupCrash", "RecursiveResourceLookupCrash\RecursiveResourceLookupCrash.csproj", "{9B5BDF7D-5816-47C6-8CFD-E45B152CA35F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SerializeTestRunTestProject", "SerializeTestRunTestProject\SerializeTestRunTestProject.csproj", "{64C4C4CD-2319-4033-9F33-53AAA8FECEFA}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -820,6 +822,18 @@ Global {9B5BDF7D-5816-47C6-8CFD-E45B152CA35F}.Release|x64.Build.0 = Release|Any CPU {9B5BDF7D-5816-47C6-8CFD-E45B152CA35F}.Release|x86.ActiveCfg = Release|Any CPU {9B5BDF7D-5816-47C6-8CFD-E45B152CA35F}.Release|x86.Build.0 = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|x64.ActiveCfg = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|x64.Build.0 = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|x86.ActiveCfg = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Debug|x86.Build.0 = Debug|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|Any CPU.Build.0 = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|x64.ActiveCfg = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|x64.Build.0 = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|x86.ActiveCfg = Release|Any CPU + {64C4C4CD-2319-4033-9F33-53AAA8FECEFA}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 5de5500925ac9c66b68aa092434f6b84751d18ac Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 10:44:04 +0100 Subject: [PATCH 02/10] address PR feedback --- .../ExtensionDecorators/SerializeTestRunDecorator.cs | 2 +- .../Resources/Resources.Designer.cs | 2 +- src/Microsoft.TestPlatform.Common/Resources/Resources.resx | 4 ++-- .../Resources/xlf/Resources.cs.xlf | 2 +- .../Resources/xlf/Resources.de.xlf | 2 +- .../Resources/xlf/Resources.es.xlf | 2 +- .../Resources/xlf/Resources.fr.xlf | 2 +- .../Resources/xlf/Resources.it.xlf | 2 +- .../Resources/xlf/Resources.ja.xlf | 2 +- .../Resources/xlf/Resources.ko.xlf | 2 +- .../Resources/xlf/Resources.pl.xlf | 2 +- .../Resources/xlf/Resources.pt-BR.xlf | 2 +- .../Resources/xlf/Resources.ru.xlf | 2 +- .../Resources/xlf/Resources.tr.xlf | 2 +- src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf | 2 +- .../Resources/xlf/Resources.zh-Hans.xlf | 2 +- .../Resources/xlf/Resources.zh-Hant.xlf | 2 +- .../TranslationLayerTests/SerializeTestRunTests.cs | 2 +- .../ExtensionFramework/ExtensionDecoratorTests.cs | 4 ++-- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs index 01e91737a1..8cb6c76863 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs @@ -93,7 +93,7 @@ private static bool IsSerializeTestRunEnabled(IRunContext? runContext) } XElement runSettings = XElement.Parse(runContext.RunSettings.SettingsXml); - XElement? serializeTestRun = runSettings.Element("RunConfiguration")?.Element("SerializeTestRun"); + XElement? serializeTestRun = runSettings.Element("RunConfiguration")?.Element("ForceOneTestAtTimePerTestHost"); return serializeTestRun is not null && bool.TryParse(serializeTestRun.Value, out bool enabled) && enabled; } diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs index 0e23a91950..77c7b6ac94 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs @@ -331,7 +331,7 @@ internal static string RunSettingsParseError { } /// - /// Looks up a localized string similar to <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run. + /// Looks up a localized string similar to <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. /// internal static string SerializeTestRunInvalidScenario { get { diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx index 33ad0caadd..51e819970e 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx @@ -208,7 +208,7 @@ An error occurred while loading the run settings. Error: {0} - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run Invalid settings node specified. The name property of the settings node must be non-empty. @@ -234,4 +234,4 @@ Types deriving from the data collection context cannot be used for sending data and messages. The DataCollectionContext used for sending data and messages must come from one of the events raised to the data collector. - \ No newline at end of file + diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf index 860e3981ef..309f048ec8 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf index 93878d2c73..82b69283d6 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf index 794589b895..8ca4731377 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf index a07ff527d9..e009dd9cc5 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf index d763b314ec..838e4c97bb 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf index 8dc012574c..5ae74fd752 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf index 3f8bd3856d..fdd7647bda 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf index 0bc6b210af..a5c5be281e 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf index 5b1a041bcb..5815d8bd6f 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf index 4c8f6ee223..cf3d613b7e 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf index 784a33e2dc..ecdb34a398 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf index 477388ca3b..ab7b2f2129 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf @@ -172,7 +172,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf index 4dbfec8ec2..07c17181ed 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf index ddb2390cd0..3c741c39ce 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf @@ -193,7 +193,7 @@ - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs index 86d59b6205..46dd023488 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs @@ -25,7 +25,7 @@ public class SerializeTestRunTests : AcceptanceTestBase private readonly string _runsettings = @" - true + true "; diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs index 917eea0098..fbfdb5e8fd 100644 --- a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs @@ -30,7 +30,7 @@ public class ExtensionDecoratorTests private readonly string _runsettings = @" - true + true "; @@ -111,7 +111,7 @@ public void SerializeTestRunDecorator_Disabled(string falseValue, bool nullRunSe string runsettings = $@" - {falseValue} + {falseValue} "; From e9ad115a51f386aadc4e5c696672cf21b515aa6d Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 11:01:25 +0100 Subject: [PATCH 03/10] add comment --- .../ExtensionFramework/Utilities/LazyExtension.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs b/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs index 8430e4493d..ca757ef2c5 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionFramework/Utilities/LazyExtension.cs @@ -102,8 +102,8 @@ public TExtension Value var pluginType = TestPluginManager.GetTestExtensionType(TestPluginInfo.AssemblyQualifiedName); TPDebug.Assert(pluginType is not null, "pluginType is null"); + // If the extension is a test executor we decorate the adapter to augment the test platform capabilities. var extension = TestPluginManager.CreateTestExtension(pluginType); - if (typeof(ITestExecutor).IsAssignableFrom(typeof(TExtension))) { extension = (TExtension)_extensionDecoratorFactory.Decorate((ITestExecutor)extension!); From 5755ab09c968a40f96946328739d7d011d59179b Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 12:53:30 +0100 Subject: [PATCH 04/10] Update src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../ExtensionDecorators/SerializeTestRunDecorator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs index 8cb6c76863..316cd23075 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs @@ -27,7 +27,7 @@ public void RunTests(IEnumerable? tests, IRunContext? runContext, IFra { if (IsSerializeTestRunEnabled(runContext)) { - EqtTrace.Info($"SerializeTestRunDecorator: Test cases will run sequentially"); + EqtTrace.Info("SerializeTestRunDecorator.RunTests: Test cases will run sequentially"); if (tests is null) { return; From c0b3ac1a21aab10268286f358b8769ff9fb66ee7 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 12:53:37 +0100 Subject: [PATCH 05/10] Update src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../ExtensionDecorators/SerializeTestRunDecorator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs index 316cd23075..b29b0d7a9d 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs @@ -16,7 +16,7 @@ internal class SerializeTestRunDecorator : ITestExecutor, ITestExecutor2, IDispo { private readonly SemaphoreSlim _runSequentialEvent = new(1); - public ITestExecutor OriginalTestExecutor { get; private set; } + public ITestExecutor OriginalTestExecutor { get; } public SerializeTestRunDecorator(ITestExecutor originalTestExecutor) { From 931aa491ec1e2d5be55e7c5a7342affb4207d72f Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 12:58:08 +0100 Subject: [PATCH 06/10] Update src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../Execution/BaseRunTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs index 155080fa8e..f30d402b11 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs @@ -495,9 +495,9 @@ private bool RunTestInternalWithExecutors(IEnumerable> execut { // If real executor is wrapped by a decorator we get the real decorated type TypeInfo executorTypeInfo = - (executor.Value is SerializeTestRunDecorator serializeTestRunDecorator) ? - serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() : - executor.Value.GetType().GetTypeInfo(); + (executor.Value is SerializeTestRunDecorator serializeTestRunDecorator) + ? serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() + : executor.Value.GetType().GetTypeInfo(); var executorLocation = executorTypeInfo.Assembly.GetAssemblyLocation(); executorsFromDeprecatedLocations |= Path.GetDirectoryName(executorLocation)!.Equals(CrossPlatEngine.Constants.DefaultAdapterLocation); From 51a5c0992b95858fdc8ee5d5e53a7cf92cc0fcdb Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 13:27:43 +0100 Subject: [PATCH 07/10] address PR feedback --- .../ExtensionDecoratorFactory.cs | 2 +- ...Decorator.cs => SerialTestRunDecorator.cs} | 14 +++--- .../SerialTestRunDecoratorFrameworkHandle.cs | 46 +++++++++++++++++++ .../Resources/Resources.Designer.cs | 6 +-- .../Resources/Resources.resx | 6 +-- .../CodeCoverageDataAttachmentsHandler.cs | 4 +- .../SerializeTestRunTests.cs | 8 ++-- .../ExtensionDecoratorTests.cs | 2 +- 8 files changed, 67 insertions(+), 21 deletions(-) rename src/Microsoft.TestPlatform.Common/ExtensionDecorators/{SerializeTestRunDecorator.cs => SerialTestRunDecorator.cs} (91%) create mode 100644 src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecoratorFrameworkHandle.cs diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs index 3478685ecc..2500025502 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs @@ -18,6 +18,6 @@ public ITestExecutor Decorate(ITestExecutor originalTestExecutor) { return _featureFlag.IsSet(FeatureFlag.DISABLE_SERIALIZETESTRUN_DECORATOR) ? originalTestExecutor - : new SerializeTestRunDecorator(originalTestExecutor); + : new SerialTestRunDecorator(originalTestExecutor); } } diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs similarity index 91% rename from src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs rename to src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs index b29b0d7a9d..9488ec12e0 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerializeTestRunDecorator.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs @@ -12,20 +12,20 @@ namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; -internal class SerializeTestRunDecorator : ITestExecutor, ITestExecutor2, IDisposable +internal class SerialTestRunDecorator : ITestExecutor, ITestExecutor2, IDisposable { private readonly SemaphoreSlim _runSequentialEvent = new(1); public ITestExecutor OriginalTestExecutor { get; } - public SerializeTestRunDecorator(ITestExecutor originalTestExecutor) + public SerialTestRunDecorator(ITestExecutor originalTestExecutor) { OriginalTestExecutor = originalTestExecutor; } public void RunTests(IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) { - if (IsSerializeTestRunEnabled(runContext)) + if (IsSerialTestRunEnabled(runContext)) { EqtTrace.Info("SerializeTestRunDecorator.RunTests: Test cases will run sequentially"); if (tests is null) @@ -47,10 +47,10 @@ public void RunTests(IEnumerable? tests, IRunContext? runContext, IFra public void RunTests(IEnumerable? sources, IRunContext? runContext, IFrameworkHandle? frameworkHandle) { - if (IsSerializeTestRunEnabled(runContext)) + if (IsSerialTestRunEnabled(runContext)) { - EqtTrace.Error(Resources.Resources.SerializeTestRunInvalidScenario); - frameworkHandle?.SendMessage(TestMessageLevel.Error, Resources.Resources.SerializeTestRunInvalidScenario); + EqtTrace.Error(Resources.Resources.SerialTestRunInvalidScenario); + frameworkHandle?.SendMessage(TestMessageLevel.Error, Resources.Resources.SerialTestRunInvalidScenario); } else { @@ -85,7 +85,7 @@ public bool ShouldAttachToTestHost(IEnumerable? tests, IRunContext run public void Cancel() => OriginalTestExecutor.Cancel(); - private static bool IsSerializeTestRunEnabled(IRunContext? runContext) + private static bool IsSerialTestRunEnabled(IRunContext? runContext) { if (runContext is null || runContext.RunSettings is null || runContext.RunSettings.SettingsXml is null) { diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecoratorFrameworkHandle.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecoratorFrameworkHandle.cs new file mode 100644 index 0000000000..2fe58fea6a --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecoratorFrameworkHandle.cs @@ -0,0 +1,46 @@ +// 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.Collections.Generic; +using System.Threading; + +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; + +namespace Microsoft.VisualStudio.TestPlatform.Common.ExtensionDecorators; + +internal class SerialTestRunDecoratorFrameworkHandle : IFrameworkHandle +{ + private readonly IFrameworkHandle _frameworkHandle; + private readonly SemaphoreSlim _testEnd; + + public SerialTestRunDecoratorFrameworkHandle(IFrameworkHandle frameworkHandle, SemaphoreSlim testEnd) + { + _frameworkHandle = frameworkHandle; + _testEnd = testEnd; + } + + public bool EnableShutdownAfterTestRun { get => _frameworkHandle.EnableShutdownAfterTestRun; set => _frameworkHandle.EnableShutdownAfterTestRun = value; } + + public int LaunchProcessWithDebuggerAttached(string filePath, string? workingDirectory, string? arguments, IDictionary? environmentVariables) + => _frameworkHandle.LaunchProcessWithDebuggerAttached(filePath, workingDirectory, arguments, environmentVariables); + + public void RecordAttachments(IList attachmentSets) + => _frameworkHandle.RecordAttachments(attachmentSets); + + public void RecordEnd(TestCase testCase, TestOutcome outcome) + { + _frameworkHandle.RecordEnd(testCase, outcome); + _testEnd.Release(); + } + + public void RecordResult(TestResult testResult) + => _frameworkHandle.RecordResult(testResult); + + public void RecordStart(TestCase testCase) + => _frameworkHandle.RecordStart(testCase); + + public void SendMessage(TestMessageLevel testMessageLevel, string message) + => _frameworkHandle.SendMessage(testMessageLevel, message); +} diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs index 77c7b6ac94..a6d36bf761 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.Designer.cs @@ -331,11 +331,11 @@ internal static string RunSettingsParseError { } /// - /// Looks up a localized string similar to <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + /// Looks up a localized string similar to <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run.. /// - internal static string SerializeTestRunInvalidScenario { + internal static string SerialTestRunInvalidScenario { get { - return ResourceManager.GetString("SerializeTestRunInvalidScenario", resourceCulture); + return ResourceManager.GetString("SerialTestRunInvalidScenario", resourceCulture); } } diff --git a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx index 51e819970e..0828045206 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/Resources.resx +++ b/src/Microsoft.TestPlatform.Common/Resources/Resources.resx @@ -207,8 +207,8 @@ An error occurred while loading the run settings. Error: {0} - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. Invalid settings node specified. The name property of the settings node must be non-empty. @@ -234,4 +234,4 @@ Types deriving from the data collection context cannot be used for sending data and messages. The DataCollectionContext used for sending data and messages must come from one of the events raised to the data collector. - + \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs index baf5d30690..5bbda6d5e0 100644 --- a/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs +++ b/src/Microsoft.TestPlatform.Utilities/CodeCoverageDataAttachmentsHandler.cs @@ -50,7 +50,7 @@ public async Task> ProcessAttachmentSetsAsync(XmlElem return new Collection(); // Merging per test code coverage is not supported - if (PerTestCoverageEnabled(configurationElement)) + if (IsPerTestCoverageEnabled(configurationElement)) { return attachments; } @@ -97,7 +97,7 @@ public async Task> ProcessAttachmentSetsAsync(XmlElem return attachments; - static bool PerTestCoverageEnabled(XmlElement? configurationElement) + static bool IsPerTestCoverageEnabled(XmlElement? configurationElement) { XmlNodeList? xmlNodeList = configurationElement?.GetElementsByTagName("PerTestCodeCoverage"); if (xmlNodeList?.Count == 1) diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs index 46dd023488..a2e57b457a 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs @@ -16,19 +16,19 @@ namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests; [TestClass] // We need to dogfood the package built in this repo *-dev and we pack tha tp only on windows [TestCategory("Windows-Review")] -public class SerializeTestRunTests : AcceptanceTestBase +public class SerialTestRunDecorator : AcceptanceTestBase { private IVsTestConsoleWrapper? _vstestConsoleWrapper; private RunEventHandler? _runEventHandler; private DiscoveryEventHandler? _discoveryEventHandler; private DiscoveryEventHandler2? _discoveryEventHandler2; - private readonly string _runsettings = @" + private readonly string _runsettings = $$""" true -"; +"""; [MemberNotNull(nameof(_vstestConsoleWrapper), nameof(_runEventHandler), nameof(_discoveryEventHandler), nameof(_discoveryEventHandler2))] private void Setup(Dictionary? environmentVariables = null) @@ -109,6 +109,6 @@ public void DiscoverTestsAndRunTestsSequentially_IsNotSupportedForSources(Runner } Assert.IsTrue(_runEventHandler.Errors.Count > 0); - Assert.IsTrue(_runEventHandler.Errors.Contains(VisualStudio.TestPlatform.Common.Resources.Resources.SerializeTestRunInvalidScenario), $"Error messages\n:{builder}"); + Assert.IsTrue(_runEventHandler.Errors.Contains(VisualStudio.TestPlatform.Common.Resources.Resources.SerialTestRunInvalidScenario), $"Error messages\n:{builder}"); } } diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs index fbfdb5e8fd..275e24b302 100644 --- a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs @@ -96,7 +96,7 @@ public void SerializeTestRunDecorator_DoesNotSupportSources() // Assert _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Never()); - _frameworkWorkHandleMock.Verify(x => x.SendMessage(TestMessageLevel.Error, Resources.SerializeTestRunInvalidScenario), Times.Once()); + _frameworkWorkHandleMock.Verify(x => x.SendMessage(TestMessageLevel.Error, Resources.SerialTestRunInvalidScenario), Times.Once()); } From b06cdfd7a483c9ab6ed95e20854f9fa1e3b691d3 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 13:28:38 +0100 Subject: [PATCH 08/10] address PR feedback --- .../ExtensionDecorators/SerialTestRunDecorator.cs | 2 +- .../Resources/xlf/Resources.cs.xlf | 6 +++--- .../Resources/xlf/Resources.de.xlf | 6 +++--- .../Resources/xlf/Resources.es.xlf | 6 +++--- .../Resources/xlf/Resources.fr.xlf | 6 +++--- .../Resources/xlf/Resources.it.xlf | 6 +++--- .../Resources/xlf/Resources.ja.xlf | 6 +++--- .../Resources/xlf/Resources.ko.xlf | 6 +++--- .../Resources/xlf/Resources.pl.xlf | 6 +++--- .../Resources/xlf/Resources.pt-BR.xlf | 6 +++--- .../Resources/xlf/Resources.ru.xlf | 6 +++--- .../Resources/xlf/Resources.tr.xlf | 6 +++--- .../Resources/xlf/Resources.xlf | 6 +++--- .../Resources/xlf/Resources.zh-Hans.xlf | 6 +++--- .../Resources/xlf/Resources.zh-Hant.xlf | 6 +++--- .../Execution/BaseRunTests.cs | 6 +++--- .../ExtensionFramework/ExtensionDecoratorTests.cs | 6 +++--- 17 files changed, 49 insertions(+), 49 deletions(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs index 9488ec12e0..d0d30977f0 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/SerialTestRunDecorator.cs @@ -49,7 +49,7 @@ public void RunTests(IEnumerable? sources, IRunContext? runContext, IFra { if (IsSerialTestRunEnabled(runContext)) { - EqtTrace.Error(Resources.Resources.SerialTestRunInvalidScenario); + EqtTrace.Error("true is not supported for sources test run."); frameworkHandle?.SendMessage(TestMessageLevel.Error, Resources.Resources.SerialTestRunInvalidScenario); } else diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf index 309f048ec8..312fb751e7 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.cs.xlf @@ -192,9 +192,9 @@ Trasování zásobníku: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf index 82b69283d6..4fe7c0bb7f 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.de.xlf @@ -192,9 +192,9 @@ Stapelüberwachung: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf index 8ca4731377..666bd6254f 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.es.xlf @@ -192,9 +192,9 @@ Seguimiento de la pila: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf index e009dd9cc5..ea2f9bc0f3 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.fr.xlf @@ -192,9 +192,9 @@ Arborescence des appels de procédure : - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf index 838e4c97bb..067ae41194 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.it.xlf @@ -192,9 +192,9 @@ Analisi dello stack: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf index 5ae74fd752..d1ed366dcc 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ja.xlf @@ -192,9 +192,9 @@ スタック トレース: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf index fdd7647bda..4b05cca5a7 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ko.xlf @@ -192,9 +192,9 @@ 스택 추적: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf index a5c5be281e..fb3f39f216 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pl.xlf @@ -192,9 +192,9 @@ Ślad stosu: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf index 5815d8bd6f..e3d59aa65c 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.pt-BR.xlf @@ -192,9 +192,9 @@ Rastreamento de pilha: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf index cf3d613b7e..0920ccea79 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.ru.xlf @@ -192,9 +192,9 @@ Трассировка стека: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf index ecdb34a398..8692a3dbf4 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.tr.xlf @@ -192,9 +192,9 @@ Yığın izleme: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf index ab7b2f2129..8d3261ebbb 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.xlf @@ -171,9 +171,9 @@ Stack trace: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf index 07c17181ed..8f43516a32 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hans.xlf @@ -192,9 +192,9 @@ 堆栈跟踪: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf index 3c741c39ce..37120a8ed7 100644 --- a/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf +++ b/src/Microsoft.TestPlatform.Common/Resources/xlf/Resources.zh-Hant.xlf @@ -192,9 +192,9 @@ 堆疊追蹤: - - <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run - <SerializeTestRun>true</SerializeTestRun> is not supported for sources test run + + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. + <ForceOneTestAtTimePerTestHost>true</ForceOneTestAtTimePerTestHost> is not supported for sources test run. diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs index f30d402b11..d0ade34883 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs @@ -495,9 +495,9 @@ private bool RunTestInternalWithExecutors(IEnumerable> execut { // If real executor is wrapped by a decorator we get the real decorated type TypeInfo executorTypeInfo = - (executor.Value is SerializeTestRunDecorator serializeTestRunDecorator) - ? serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() - : executor.Value.GetType().GetTypeInfo(); + (executor.Value is SerialTestRunDecorator serializeTestRunDecorator) + ? serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() + : executor.Value.GetType().GetTypeInfo(); var executorLocation = executorTypeInfo.Assembly.GetAssemblyLocation(); executorsFromDeprecatedLocations |= Path.GetDirectoryName(executorLocation)!.Equals(CrossPlatEngine.Constants.DefaultAdapterLocation); diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs index 275e24b302..cdc9cd9633 100644 --- a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs @@ -76,7 +76,7 @@ public void SerializeTestRunDecorator_ShouldSerializeTests() }); // Run test - SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); // Assert @@ -91,7 +91,7 @@ public void SerializeTestRunDecorator_DoesNotSupportSources() _contextMock.Setup(x => x.RunSettings).Returns(_settingsMock.Object); // Run test - SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); serializeTestRunDecorator.RunTests(new List() { "samplesource.dll" }, _contextMock.Object, _frameworkWorkHandleMock.Object); // Assert @@ -131,7 +131,7 @@ public void SerializeTestRunDecorator_Disabled(string falseValue, bool nullRunSe .Callback((IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => Assert.AreEqual(sourcesName, tests)); // Run test - SerializeTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); + SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); serializeTestRunDecorator.RunTests(sourcesName, _contextMock.Object, _frameworkWorkHandleMock.Object); From acd236050cd3b8d2d4c3f9ed00bf513180f3e3f2 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 13:58:52 +0100 Subject: [PATCH 09/10] address PR feedback --- .../ExtensionDecoratorFactory.cs | 2 +- .../FeatureFlag/FeatureFlag.cs | 4 ++-- .../SerializeTestRunTests.cs | 2 +- .../ExtensionDecoratorTests.cs | 22 +++++++++---------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs index 2500025502..758cef6fc7 100644 --- a/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs +++ b/src/Microsoft.TestPlatform.Common/ExtensionDecorators/ExtensionDecoratorFactory.cs @@ -16,7 +16,7 @@ public ExtensionDecoratorFactory(IFeatureFlag featureFlag) public ITestExecutor Decorate(ITestExecutor originalTestExecutor) { - return _featureFlag.IsSet(FeatureFlag.DISABLE_SERIALIZETESTRUN_DECORATOR) + return _featureFlag.IsSet(FeatureFlag.DISABLE_SERIALTESTRUN_DECORATOR) ? originalTestExecutor : new SerialTestRunDecorator(originalTestExecutor); } diff --git a/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs b/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs index c70581f59f..c6a38f1b9b 100644 --- a/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs +++ b/src/Microsoft.TestPlatform.CoreUtilities/FeatureFlag/FeatureFlag.cs @@ -54,8 +54,8 @@ private FeatureFlag() { } // even though we are blocking additional threads becuase we don't have to wait for ThreadPool to start more threads. public const string DISABLE_THREADPOOL_SIZE_INCREASE = VSTEST_ + nameof(DISABLE_THREADPOOL_SIZE_INCREASE); - // Disable the SerializeTestRunDecorator - public const string DISABLE_SERIALIZETESTRUN_DECORATOR = VSTEST_ + nameof(DISABLE_SERIALIZETESTRUN_DECORATOR); + // Disable the SerialTestRunDecorator + public const string DISABLE_SERIALTESTRUN_DECORATOR = VSTEST_ + nameof(DISABLE_SERIALTESTRUN_DECORATOR); [Obsolete("Only use this in tests.")] internal static void Reset() diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs index a2e57b457a..48870919e1 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/SerializeTestRunTests.cs @@ -73,7 +73,7 @@ public void DiscoverTestsAndRunTestsSequentially_DisabledByFeatureFlag(RunnerInf { // Arrange SetTestEnvironment(_testEnvironment, runnerInfo); - Dictionary? environmentVariables = new() { { "VSTEST_DISABLE_SERIALIZETESTRUN_DECORATOR", "1" } }; + Dictionary? environmentVariables = new() { { "VSTEST_DISABLE_SERIALTESTRUN_DECORATOR", "1" } }; Setup(environmentVariables); // Act diff --git a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs index cdc9cd9633..ac1e85826a 100644 --- a/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs +++ b/test/Microsoft.TestPlatform.Common.UnitTests/ExtensionFramework/ExtensionDecoratorTests.cs @@ -38,7 +38,7 @@ public class ExtensionDecoratorTests public void ExtensionDecoratorFactory_DisabledByFlag() { // Arrange - _featureFlagMock.Setup(x => x.IsSet(FeatureFlag.DISABLE_SERIALIZETESTRUN_DECORATOR)).Returns(true); + _featureFlagMock.Setup(x => x.IsSet(FeatureFlag.DISABLE_SERIALTESTRUN_DECORATOR)).Returns(true); // Run test and assert ExtensionDecoratorFactory extensionDecoratorFactory = new(_featureFlagMock.Object); @@ -47,7 +47,7 @@ public void ExtensionDecoratorFactory_DisabledByFlag() } [TestMethod] - public void SerializeTestRunDecorator_ShouldSerializeTests() + public void SerialTestRunDecorator_ShouldSerializeTests() { // Arrange List testCases = new(); @@ -76,23 +76,23 @@ public void SerializeTestRunDecorator_ShouldSerializeTests() }); // Run test - SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); - serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); + SerialTestRunDecorator serialTestRunDecorator = new(_testExecutorMock.Object); + serialTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); // Assert Assert.AreEqual(0, testCases.Except(testCasesRan).Count()); } [TestMethod] - public void SerializeTestRunDecorator_DoesNotSupportSources() + public void SerialTestRunDecorator_DoesNotSupportSources() { // Arrange _settingsMock.Setup(x => x.SettingsXml).Returns(_runsettings); _contextMock.Setup(x => x.RunSettings).Returns(_settingsMock.Object); // Run test - SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); - serializeTestRunDecorator.RunTests(new List() { "samplesource.dll" }, _contextMock.Object, _frameworkWorkHandleMock.Object); + SerialTestRunDecorator serialTestRunDecorator = new(_testExecutorMock.Object); + serialTestRunDecorator.RunTests(new List() { "samplesource.dll" }, _contextMock.Object, _frameworkWorkHandleMock.Object); // Assert _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Never()); @@ -105,7 +105,7 @@ public void SerializeTestRunDecorator_DoesNotSupportSources() [DataRow("false", false)] [DataRow("FALSE", false)] [DataRow(null, true)] - public void SerializeTestRunDecorator_Disabled(string falseValue, bool nullRunSettings) + public void SerialTestRunDecorator_Disabled(string falseValue, bool nullRunSettings) { // Arrange string runsettings = $@" @@ -131,9 +131,9 @@ public void SerializeTestRunDecorator_Disabled(string falseValue, bool nullRunSe .Callback((IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => Assert.AreEqual(sourcesName, tests)); // Run test - SerialTestRunDecorator serializeTestRunDecorator = new(_testExecutorMock.Object); - serializeTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); - serializeTestRunDecorator.RunTests(sourcesName, _contextMock.Object, _frameworkWorkHandleMock.Object); + SerialTestRunDecorator serialTestRunDecorator = new(_testExecutorMock.Object); + serialTestRunDecorator.RunTests(testCases, _contextMock.Object, _frameworkWorkHandleMock.Object); + serialTestRunDecorator.RunTests(sourcesName, _contextMock.Object, _frameworkWorkHandleMock.Object); // Assert _testExecutorMock.Verify(x => x.RunTests(It.IsAny?>(), It.IsAny(), It.IsAny()), Times.Once()); From f5e96a89be078740bc7efd8ad146d2aca14654ae Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Mon, 28 Nov 2022 14:00:44 +0100 Subject: [PATCH 10/10] address PR feedback --- .../Execution/BaseRunTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs index d0ade34883..8b4b745e7f 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs @@ -495,8 +495,8 @@ private bool RunTestInternalWithExecutors(IEnumerable> execut { // If real executor is wrapped by a decorator we get the real decorated type TypeInfo executorTypeInfo = - (executor.Value is SerialTestRunDecorator serializeTestRunDecorator) - ? serializeTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() + (executor.Value is SerialTestRunDecorator serialTestRunDecorator) + ? serialTestRunDecorator.OriginalTestExecutor.GetType().GetTypeInfo() : executor.Value.GetType().GetTypeInfo(); var executorLocation = executorTypeInfo.Assembly.GetAssemblyLocation();