From f179116cbc928875c80ade24e082ede7f8d9bbcc Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Mon, 3 Feb 2025 12:00:49 +0100 Subject: [PATCH] Cleanup filter-related logic --- .../MSTestBridgedTestFramework.cs | 9 +-- .../TestApplicationBuilderExtensions.cs | 1 + .../ObjectModel/ContextAdapterBase.cs | 77 ++++++++++++++++++- .../ObjectModel/DiscoveryContextAdapter.cs | 5 +- .../ObjectModel/RunContextAdapter.cs | 64 +-------------- .../ObjectModel/TreeNodeFilterExpression.cs | 27 +++++++ .../VSTestDiscoverTestExecutionRequest.cs | 5 +- ...TestDiscoverTestExecutionRequestFactory.cs | 43 +++-------- .../Requests/VSTestRunTestExecutionRequest.cs | 13 +++- .../VSTestRunTestExecutionRequestFactory.cs | 42 +++------- .../Requests/VSTestTestExecutionFilter.cs | 7 +- .../VSTestBridgedTestFrameworkBase.cs | 6 +- 12 files changed, 151 insertions(+), 148 deletions(-) create mode 100644 src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/TreeNodeFilterExpression.cs diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs index 44723557f9..f05ebcdd37 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs @@ -54,14 +54,7 @@ protected override async Task SynchronizedRunTestsAsync(VSTestRunTestExecutionRe PlatformServiceProvider.Instance.AdapterTraceLogger = new BridgedTraceLogger(_loggerFactory.CreateLogger("mstest-trace")); MSTestExecutor testExecutor = new(cancellationToken); - if (request.VSTestFilter.TestCases is { } testCases) - { - await testExecutor.RunTestsAsync(testCases, request.RunContext, request.FrameworkHandle, _configuration); - } - else - { - await testExecutor.RunTestsAsync(request.AssemblyPaths, request.RunContext, request.FrameworkHandle, _configuration); - } + await testExecutor.RunTestsAsync(request.AssemblyPaths, request.RunContext, request.FrameworkHandle, _configuration); } } #endif diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs index 436ce80215..d42bf925d7 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs @@ -28,6 +28,7 @@ public static void AddMSTest(this ITestApplicationBuilder testApplicationBuilder testApplicationBuilder.AddRunSettingsService(extension); testApplicationBuilder.AddTestCaseFilterService(extension); testApplicationBuilder.AddTestRunParametersService(extension); + testApplicationBuilder.AddTreeNodeFilterService(extension); #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. testApplicationBuilder.AddMaximumFailedTestsService(extension); #pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs index e79410734a..3d60ed7e26 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs @@ -4,6 +4,8 @@ using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Requests; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; @@ -11,7 +13,7 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; internal abstract class ContextAdapterBase { - public ContextAdapterBase(ICommandLineOptions commandLineOptions) + protected ContextAdapterBase(ICommandLineOptions commandLineOptions, ITestExecutionFilter filter) { if (commandLineOptions.TryGetOptionArgumentList( TestCaseFilterCommandLineOptionsProvider.TestCaseFilterOptionName, @@ -21,16 +23,34 @@ public ContextAdapterBase(ICommandLineOptions commandLineOptions) { FilterExpressionWrapper = new(filterExpressions[0]); } + + switch (filter) + { + case TestNodeUidListFilter uidListFilter: + FilterExpressionWrapper = new(CreateFilter(uidListFilter.TestNodeUids)); + break; + + case TreeNodeFilter treeNodeFilter: + TreeNodeFilter = treeNodeFilter; + break; + } } protected FilterExpressionWrapper? FilterExpressionWrapper { get; set; } + protected TreeNodeFilter? TreeNodeFilter { get; set; } + // NOTE: Implementation is borrowed from VSTest // MSTest relies on this method existing and access it through reflection: https://github.com/microsoft/testfx/blob/main/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs#L115 public ITestCaseFilterExpression? GetTestCaseFilter( IEnumerable? supportedProperties, Func propertyProvider) { + if (TreeNodeFilter is not null) + { + return new TreeNodeFilterExpression(TreeNodeFilter, supportedProperties, propertyProvider); + } + if (FilterExpressionWrapper is null) { return null; @@ -61,4 +81,59 @@ public ContextAdapterBase(ICommandLineOptions commandLineOptions) return adapterSpecificTestCaseFilter; } + + // We use heuristic to understand if the filter should be a TestCaseId or FullyQualifiedName. + // We know that in VSTest TestCaseId is a GUID and FullyQualifiedName is a string. + private static string CreateFilter(TestNodeUid[] testNodesUid) + { + StringBuilder filter = new(); + + for (int i = 0; i < testNodesUid.Length; i++) + { + if (Guid.TryParse(testNodesUid[i].Value, out Guid guid)) + { + filter.Append("Id="); + filter.Append(guid.ToString()); + } + else + { + TestNodeUid currentTestNodeUid = testNodesUid[i]; + filter.Append("FullyQualifiedName="); + for (int k = 0; k < currentTestNodeUid.Value.Length; k++) + { + char currentChar = currentTestNodeUid.Value[k]; + switch (currentChar) + { + case '\\': + case '(': + case ')': + case '&': + case '|': + case '=': + case '!': + case '~': + // If the symbol is not escaped, add an escape character. + if (i - 1 < 0 || currentTestNodeUid.Value[k - 1] != '\\') + { + filter.Append('\\'); + } + + filter.Append(currentChar); + break; + + default: + filter.Append(currentChar); + break; + } + } + } + + if (i != testNodesUid.Length - 1) + { + filter.Append('|'); + } + } + + return filter.ToString(); + } } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/DiscoveryContextAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/DiscoveryContextAdapter.cs index 8db368b6ae..59efdff4c6 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/DiscoveryContextAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/DiscoveryContextAdapter.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Requests; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; @@ -11,8 +12,8 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; /// internal sealed class DiscoveryContextAdapter : ContextAdapterBase, IDiscoveryContext { - public DiscoveryContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings? runSettings = null) - : base(commandLineOptions) => RunSettings = runSettings; + public DiscoveryContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings? runSettings, ITestExecutionFilter filter) + : base(commandLineOptions, filter) => RunSettings = runSettings; public IRunSettings? RunSettings { get; } } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs index 48ab8bbb84..4302a98127 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs @@ -3,7 +3,7 @@ using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.CommandLine; -using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Requests; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; @@ -13,8 +13,8 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; /// internal sealed class RunContextAdapter : ContextAdapterBase, IRunContext { - public RunContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings runSettings) - : base(commandLineOptions) + public RunContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings runSettings, ITestExecutionFilter filter) + : base(commandLineOptions, filter) { RoslynDebug.Assert(runSettings.SettingsXml is not null); @@ -24,9 +24,6 @@ public RunContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings ru TestRunDirectory = XElement.Parse(runSettings.SettingsXml).Descendants("ResultsDirectory").SingleOrDefault()?.Value; } - public RunContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings runSettings, TestNodeUid[] testNodeUids) - : this(commandLineOptions, runSettings) => FilterExpressionWrapper = new(CreateFilter(testNodeUids)); - // NOTE: Always false as it's TPv2 oriented and so not applicable to TA. /// @@ -53,59 +50,4 @@ public RunContextAdapter(ICommandLineOptions commandLineOptions, IRunSettings ru /// public IRunSettings? RunSettings { get; } - - // We use heuristic to understand if the filter should be a TestCaseId or FullyQualifiedName. - // We know that in VSTest TestCaseId is a GUID and FullyQualifiedName is a string. - private static string CreateFilter(TestNodeUid[] testNodesUid) - { - StringBuilder filter = new(); - - for (int i = 0; i < testNodesUid.Length; i++) - { - if (Guid.TryParse(testNodesUid[i].Value, out Guid guid)) - { - filter.Append("Id="); - filter.Append(guid.ToString()); - } - else - { - TestNodeUid currentTestNodeUid = testNodesUid[i]; - filter.Append("FullyQualifiedName="); - for (int k = 0; k < currentTestNodeUid.Value.Length; k++) - { - char currentChar = currentTestNodeUid.Value[k]; - switch (currentChar) - { - case '\\': - case '(': - case ')': - case '&': - case '|': - case '=': - case '!': - case '~': - // If the symbol is not escaped, add an escape character. - if (i - 1 < 0 || currentTestNodeUid.Value[k - 1] != '\\') - { - filter.Append('\\'); - } - - filter.Append(currentChar); - break; - - default: - filter.Append(currentChar); - break; - } - } - } - - if (i != testNodesUid.Length - 1) - { - filter.Append('|'); - } - } - - return filter.ToString(); - } } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/TreeNodeFilterExpression.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/TreeNodeFilterExpression.cs new file mode 100644 index 0000000000..b811e22bdc --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/TreeNodeFilterExpression.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Testing.Platform.Requests; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; + +namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; + +internal sealed class TreeNodeFilterExpression : ITestCaseFilterExpression +{ + private TreeNodeFilter _treeNodeFilter; + private IEnumerable? _supportedProperties; + private Func _propertyProvider; + + public TreeNodeFilterExpression(TreeNodeFilter treeNodeFilter, IEnumerable? supportedProperties, Func propertyProvider) + { + _treeNodeFilter = treeNodeFilter; + _supportedProperties = supportedProperties; + _propertyProvider = propertyProvider; + } + + public string TestCaseFilterValue => _treeNodeFilter.Filter; + + public bool MatchTestCase(TestCase testCase, Func propertyValueProvider) + => true; +} diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequest.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequest.cs index 7e737c256b..1982cbe02d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequest.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequest.cs @@ -13,7 +13,7 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; /// public sealed class VSTestDiscoverTestExecutionRequest : DiscoverTestExecutionRequest { - internal VSTestDiscoverTestExecutionRequest(TestSessionContext session, VSTestTestExecutionFilter executionFilter, string[] assemblyPaths, + internal VSTestDiscoverTestExecutionRequest(TestSessionContext session, ITestExecutionFilter executionFilter, string[] assemblyPaths, IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink) : base(session, executionFilter) { @@ -23,8 +23,9 @@ internal VSTestDiscoverTestExecutionRequest(TestSessionContext session, VSTestTe DiscoverySink = discoverySink; } + [Obsolete("VSTestTestExecutionFilter always have null TestCases and should not be used.", error: true)] public VSTestTestExecutionFilter VSTestFilter - => (VSTestTestExecutionFilter)Filter; + => VSTestTestExecutionFilter.Instance; public string[] AssemblyPaths { get; } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequestFactory.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequestFactory.cs index ec96c1b585..2831435e23 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequestFactory.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestDiscoverTestExecutionRequestFactory.cs @@ -3,20 +3,15 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using Microsoft.Testing.Extensions.VSTestBridge.Capabilities; using Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; -using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; -using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.OutputDevice; using Microsoft.Testing.Platform.Requests; using Microsoft.Testing.Platform.Services; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; @@ -25,37 +20,17 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; /// public sealed class VSTestDiscoverTestExecutionRequestFactory : ITestExecutionRequestFactory { - private readonly ITestFrameworkCapabilities _testFrameworkCapabilities; - private readonly ITestFramework _testFrameworkAdapter; - private readonly ICommandLineOptions _commandLineService; - private readonly string[] _assemblyPaths; - private readonly VSTestTestExecutionFilter _testExecutionFilter; - private readonly IDiscoveryContext _discoveryContext; - private readonly IMessageLogger _messageLogger; - private readonly ITestCaseDiscoverySink _discoverySink; - - internal VSTestDiscoverTestExecutionRequestFactory(ITestFrameworkCapabilities testFrameworkCapabilities, ITestFramework testFrameworkAdapter, - ICommandLineOptions commandLineService, string[] assemblyPaths, VSTestTestExecutionFilter testExecutionFilter, - IDiscoveryContext discoveryContext, IMessageLogger messageLogger, ITestCaseDiscoverySink discoverySink) + [Obsolete] + private VSTestDiscoverTestExecutionRequestFactory() { - _testFrameworkCapabilities = testFrameworkCapabilities; - _testFrameworkAdapter = testFrameworkAdapter; - _commandLineService = commandLineService; - _assemblyPaths = assemblyPaths; - _discoveryContext = discoveryContext; - _messageLogger = messageLogger; - _discoverySink = discoverySink; - _testExecutionFilter = testExecutionFilter; } + // This class is never instantiated. + // It's not possible to reach this method. + // The class should probably be static and not needing to implement the interface. + [Obsolete] Task ITestExecutionRequestFactory.CreateRequestAsync(Platform.TestHost.TestSessionContext session) - => !_commandLineService.IsOptionSet(PlatformCommandLineProvider.VSTestAdapterModeOptionKey) - ? throw new InvalidOperationException($"Command line argument {PlatformCommandLineProvider.VSTestAdapterModeOptionKey} is not set but we are in VSTest adapter mode. This is a bug in the adapter.") - : _testFrameworkCapabilities.GetCapability()?.IsSupported != true - ? throw new InvalidOperationException($"Skipping test adapter {_testFrameworkAdapter.DisplayName} because it is not {nameof(IVSTestFlattenedTestNodesReportCapability)} capable.") - : !_commandLineService.IsOptionSet(PlatformCommandLineProvider.DiscoverTestsOptionKey) - ? throw new NotSupportedException($"The {nameof(VSTestRunTestExecutionRequestFactory)} does not support creating a {nameof(DiscoverTestExecutionRequest)}.") - : Task.FromResult(new VSTestDiscoverTestExecutionRequest(session, _testExecutionFilter, _assemblyPaths, _discoveryContext, _messageLogger, _discoverySink)); + => throw ApplicationStateGuard.Unreachable(); public static VSTestDiscoverTestExecutionRequest CreateRequest( DiscoverTestExecutionRequest discoverTestExecutionRequest, @@ -72,12 +47,12 @@ public static VSTestDiscoverTestExecutionRequest CreateRequest( ICommandLineOptions commandLineOptions = serviceProvider.GetRequiredService(); RunSettingsAdapter runSettings = new(commandLineOptions, fileSystem, configuration, clientInfo, loggerFactory, messageLogger); - DiscoveryContextAdapter discoveryContext = new(commandLineOptions, runSettings); + DiscoveryContextAdapter discoveryContext = new(commandLineOptions, runSettings, discoverTestExecutionRequest.Filter); ITestApplicationModuleInfo testApplicationModuleInfo = serviceProvider.GetTestApplicationModuleInfo(); IMessageBus messageBus = serviceProvider.GetRequiredService(); TestCaseDiscoverySinkAdapter discoverySink = new(adapterExtension, discoverTestExecutionRequest.Session, testAssemblyPaths, testApplicationModuleInfo, loggerFactory, messageBus, adapterExtension.IsTrxEnabled, clientInfo, cancellationToken); - return new(discoverTestExecutionRequest.Session, new(), testAssemblyPaths, discoveryContext, messageLogger, discoverySink); + return new(discoverTestExecutionRequest.Session, discoverTestExecutionRequest.Filter, testAssemblyPaths, discoveryContext, messageLogger, discoverySink); } } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequest.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequest.cs index c0d52e8cb9..8e6c91ddea 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequest.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequest.cs @@ -12,6 +12,7 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; /// public sealed class VSTestRunTestExecutionRequest : RunTestExecutionRequest { + [Obsolete("VSTestTestExecutionFilter always have null TestCases and should not be used.", error: true)] public VSTestRunTestExecutionRequest(TestSessionContext session, VSTestTestExecutionFilter executionFilter, string[] assemblyPaths, IRunContext runContext, IFrameworkHandle frameworkHandle) : base(session, executionFilter) @@ -21,8 +22,18 @@ public VSTestRunTestExecutionRequest(TestSessionContext session, VSTestTestExecu FrameworkHandle = frameworkHandle; } + internal VSTestRunTestExecutionRequest(TestSessionContext session, ITestExecutionFilter executionFilter, string[] assemblyPaths, + IRunContext runContext, IFrameworkHandle frameworkHandle) + : base(session, executionFilter) + { + AssemblyPaths = assemblyPaths; + RunContext = runContext; + FrameworkHandle = frameworkHandle; + } + + [Obsolete("VSTestTestExecutionFilter always have null TestCases and should not be used.", error: true)] public VSTestTestExecutionFilter VSTestFilter - => (VSTestTestExecutionFilter)Filter; + => VSTestTestExecutionFilter.Instance; public string[] AssemblyPaths { get; } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequestFactory.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequestFactory.cs index 50a4698376..f3cc89d345 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequestFactory.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestRunTestExecutionRequestFactory.cs @@ -3,19 +3,15 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using Microsoft.Testing.Extensions.VSTestBridge.Capabilities; using Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; -using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; -using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.OutputDevice; using Microsoft.Testing.Platform.Requests; using Microsoft.Testing.Platform.Services; -using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; @@ -24,35 +20,17 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; /// public sealed class VSTestRunTestExecutionRequestFactory : ITestExecutionRequestFactory { - private readonly ITestFrameworkCapabilities _testFrameworkCapabilities; - private readonly ITestFramework _testFrameworkAdapter; - private readonly ICommandLineOptions _commandLineService; - private readonly string[] _assemblyPaths; - private readonly VSTestTestExecutionFilter _testExecutionFilter; - private readonly IRunContext _runContext; - private readonly IFrameworkHandle _frameworkHandle; - - internal VSTestRunTestExecutionRequestFactory(ITestFrameworkCapabilities testFrameworkCapabilities, ITestFramework testFrameworkAdapter, - ICommandLineOptions commandLineService, string[] assemblyPaths, VSTestTestExecutionFilter testExecutionFilter, - IRunContext runContext, IFrameworkHandle frameworkHandle) + [Obsolete] + private VSTestRunTestExecutionRequestFactory() { - _testFrameworkCapabilities = testFrameworkCapabilities; - _testFrameworkAdapter = testFrameworkAdapter; - _commandLineService = commandLineService; - _assemblyPaths = assemblyPaths; - _testExecutionFilter = testExecutionFilter; - _runContext = runContext; - _frameworkHandle = frameworkHandle; } + // This class is never instantiated. + // It's not possible to reach this method. + // The class should probably be static and not needing to implement the interface. + [Obsolete] Task ITestExecutionRequestFactory.CreateRequestAsync(Platform.TestHost.TestSessionContext session) - => !_commandLineService.IsOptionSet(PlatformCommandLineProvider.VSTestAdapterModeOptionKey) - ? throw new InvalidOperationException($"Command line argument {PlatformCommandLineProvider.VSTestAdapterModeOptionKey} is not set but we are in VSTest adapter mode. This is a bug in the adapter.") - : _testFrameworkCapabilities.GetCapability()?.IsSupported != true - ? throw new InvalidOperationException($"Skipping test adapter {_testFrameworkAdapter.DisplayName} because it is not {nameof(IVSTestFlattenedTestNodesReportCapability)} capable.") - : _commandLineService.IsOptionSet(PlatformCommandLineProvider.DiscoverTestsOptionKey) - ? throw new NotSupportedException($"The {nameof(VSTestRunTestExecutionRequestFactory)} does not support creating a {nameof(DiscoverTestExecutionRequest)}.") - : Task.FromResult(new VSTestRunTestExecutionRequest(session, _testExecutionFilter, _assemblyPaths, _runContext, _frameworkHandle)); + => throw ApplicationStateGuard.Unreachable(); /// /// Helper method to convert a to a . @@ -81,10 +59,8 @@ public static VSTestRunTestExecutionRequest CreateRequest( testApplicationModuleInfo, loggerFactory, messageBus, outputDevice, adapterExtension.IsTrxEnabled, cancellationToken); RunSettingsAdapter runSettings = new(commandLineOptions, fileSystem, configuration, clientInfo, loggerFactory, frameworkHandlerAdapter); - RunContextAdapter runContext = runTestExecutionRequest.Filter is TestNodeUidListFilter uidListFilter - ? new(commandLineOptions, runSettings, uidListFilter.TestNodeUids) - : new(commandLineOptions, runSettings); + RunContextAdapter runContext = new(commandLineOptions, runSettings, runTestExecutionRequest.Filter); - return new(runTestExecutionRequest.Session, new(), testAssemblyPaths, runContext, frameworkHandlerAdapter); + return new(runTestExecutionRequest.Session, runTestExecutionRequest.Filter, testAssemblyPaths, runContext, frameworkHandlerAdapter); } } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestTestExecutionFilter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestTestExecutionFilter.cs index 7469195091..bdca295449 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestTestExecutionFilter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Requests/VSTestTestExecutionFilter.cs @@ -11,13 +11,14 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.Requests; /// /// A specialized test execution filter for VSTest. It contains the VSTest specific properties. /// +[Obsolete] public sealed class VSTestTestExecutionFilter : ITestExecutionFilter { - internal VSTestTestExecutionFilter() + private VSTestTestExecutionFilter() { } - internal VSTestTestExecutionFilter(ImmutableArray testCases) => TestCases = testCases; - public ImmutableArray? TestCases { get; } + + internal static VSTestTestExecutionFilter Instance { get; } = new(); } diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/VSTestBridgedTestFrameworkBase.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/VSTestBridgedTestFrameworkBase.cs index 9316865cb2..e70ff17866 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/VSTestBridgedTestFrameworkBase.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/VSTestBridgedTestFrameworkBase.cs @@ -60,7 +60,7 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context) try { DebugUtils.LaunchAttachDebugger(); - + Debugger.Launch(); Task convertedRequest = context.Request switch { VSTestDiscoverTestExecutionRequest discoverRequest => @@ -109,7 +109,7 @@ private VSTestDiscoverTestExecutionRequest UpdateDiscoverRequest( IClientInfo clientInfo = ServiceProvider.GetRequiredService(); TestCaseDiscoverySinkAdapter testCaseDiscoverySinkAdapter = new(this, discoverRequest.Session, discoverRequest.AssemblyPaths, testApplicationModuleInfo, loggerFactory, messageBus, IsTrxEnabled, clientInfo, cancellationToken, discoverRequest.DiscoverySink); - return new(discoverRequest.Session, discoverRequest.VSTestFilter, discoverRequest.AssemblyPaths, discoverRequest.DiscoveryContext, + return new(discoverRequest.Session, discoverRequest.Filter, discoverRequest.AssemblyPaths, discoverRequest.DiscoveryContext, discoverRequest.MessageLogger, testCaseDiscoverySinkAdapter); } @@ -125,7 +125,7 @@ private VSTestRunTestExecutionRequest UpdateRunRequest(VSTestRunTestExecutionReq FrameworkHandlerAdapter frameworkHandlerAdapter = new(this, runRequest.Session, clientInfo, runRequest.AssemblyPaths, testApplicationModuleInfo, loggerFactory, messageBus, outputDevice, IsTrxEnabled, cancellationToken, runRequest.FrameworkHandle); - return new(runRequest.Session, runRequest.VSTestFilter, runRequest.AssemblyPaths, runRequest.RunContext, + return new(runRequest.Session, runRequest.Filter, runRequest.AssemblyPaths, runRequest.RunContext, frameworkHandlerAdapter); } }