From 01df3aaefc77b4cb1fd1fae7cfa7ddc48fffc6d3 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Mon, 22 Nov 2021 21:00:40 +0100 Subject: [PATCH 01/31] initial implem --- scripts/build/TestPlatform.Dependencies.props | 2 +- .../DesignMode/DesignModeClient.cs | 11 +- .../Discovery/DiscoveryRequest.cs | 37 +++++ .../RequestHelper/ITestRequestManager.cs | 5 + .../IParallelProxyDiscoveryManager.cs | 10 ++ .../ClientProtocol/IProxyDiscoveryManager.cs | 6 + .../TesthostProtocol/IDiscoveryManager.cs | 6 + .../Interfaces/ITestRequestSender.cs | 5 + .../JsonDataSerializer.cs | 1 + .../Messages/DiscoveryCompletePayload.cs | 15 ++ .../TestRequestSender.cs | 31 ++++- .../Client/InProcessProxyDiscoveryManager.cs | 6 + .../ParallelDiscoveryDataAggregator.cs | 59 ++++++++ .../ParallelDiscoveryEventsHandler.cs | 75 +++++++++- .../Parallel/ParallelProxyDiscoveryManager.cs | 37 ++++- .../Client/ProxyDiscoveryManager.cs | 14 ++ .../Discovery/DiscovererEnumerator.cs | 4 +- .../Discovery/DiscoveryManager.cs | 131 +++++++++++++++++- .../EventHandlers/TestRequestHandler.cs | 17 ++- .../Events/DiscoveryCompleteEventArgs.cs | 33 +++++ .../Client/Interfaces/IDiscoveryRequest.cs | 5 + .../Constants.cs | 7 +- .../VsTestConsoleRequestSender.cs | 18 ++- .../Discovery/DiscoveryRequestTests.cs | 11 ++ 24 files changed, 515 insertions(+), 31 deletions(-) diff --git a/scripts/build/TestPlatform.Dependencies.props b/scripts/build/TestPlatform.Dependencies.props index df99f5b7b8..5d223b7ea9 100644 --- a/scripts/build/TestPlatform.Dependencies.props +++ b/scripts/build/TestPlatform.Dependencies.props @@ -1,4 +1,4 @@ - + 15.8.3247 diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index 31812dacfa..72b2c6569d 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -226,7 +226,16 @@ private void ProcessRequests(ITestRequestManager testRequestManager) case MessageType.CancelDiscovery: { - testRequestManager.CancelDiscovery(); + // If testhost has old version, we should use old cancel logic + // to be consistent and not create regression issues + if (this.protocolConfig.Version < ObjectModel.Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) + { + testRequestManager.CancelDiscovery(); + } + else + { + testRequestManager.CancelDiscoveryWithEventHandler(); + } break; } diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index d63a2508e2..c37c26f96f 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -143,6 +143,43 @@ public void Abort() } } + /// + public void AbortWithEventHandler() + { + if (EqtTrace.IsVerboseEnabled) + { + EqtTrace.Verbose("DiscoveryRequest.AbortWithEventHandler: Aborting."); + } + + lock (this.syncObject) + { + if (this.disposed) + { + throw new ObjectDisposedException("DiscoveryRequest"); + } + + if (this.discoveryInProgress) + { + // Using DiscoveryRequest.HandleDiscoveryComplete eventHandler + this.DiscoveryManager.Abort(this); + } + else + { + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: No operation to abort."); + } + + return; + } + } + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: Aborted."); + } + } + /// /// Wait for discovery completion /// diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index 714e1df9cb..de8ffe1fde 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -102,6 +102,11 @@ void StartTestSession( /// void CancelDiscovery(); + /// + /// Cancels the current discovery request with discovery complete event handle + /// + void CancelDiscoveryWithEventHandler(); + /// /// Cancels the current test run attachments processing request. /// diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs index 908b744543..467ea8a990 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs @@ -25,4 +25,14 @@ bool HandlePartialDiscoveryComplete( IEnumerable lastChunk, bool isAborted); } + + /// + /// Enums for indicating discovery status of source + /// + public enum DiscoveryStatus + { + FullyDiscovered, // FullyDiscovered means that source was fully discovered + PartiallyDiscovered, // PartiallyDiscovered means that we started discovery of the source but smth happened (cancel/abort) and we stop processing it + NotDiscovered // Sources which were not touched during discovery + } } diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs index c77c525236..e03bdf3616 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs @@ -28,6 +28,12 @@ public interface IProxyDiscoveryManager /// void Abort(); + /// + /// Aborts discovery operation with EventHandler. + /// + /// EventHandler for handling discovery events from Engine + void Abort(ITestDiscoveryEventsHandler2 eventHandler); + /// /// Closes the current test operation. /// Send a EndSession message to close the test host and channel gracefully. diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs index e60787a968..1a7c01bcda 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs @@ -29,5 +29,11 @@ public interface IDiscoveryManager /// Aborts the test discovery. /// void Abort(); + + /// + /// Aborts the test discovery with eventHandler + /// + /// EventHandler for handling discovery events from Engine + void Abort(ITestDiscoveryEventsHandler2 eventHandler); } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs index d65aa7bb0f..950c0ff6f6 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs @@ -87,6 +87,11 @@ public interface ITestRequestSender : IDisposable /// void SendTestRunAbort(); + /// + /// Send the request to abort the discovery + /// + void SendDiscoveryAbort(); + /// /// Handle client process exit /// diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs index 72c44d1e6c..969f5b69f9 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs @@ -230,6 +230,7 @@ private JsonSerializer GetPayloadSerializer(int? version) case 2: case 4: case 5: + case 6: return payloadSerializer2; default: throw new NotSupportedException($"Protocol version {version} is not supported. " + diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs index 1abacd4f4e..4586d0773a 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs @@ -30,5 +30,20 @@ public class DiscoveryCompletePayload /// Gets or sets the Metrics /// public IDictionary Metrics { get; set; } + + /// + /// Gets or sets list of sources which were fully discovered + /// + public IReadOnlyCollection FullyDiscoveredSources { get; set; } = new List(); + + /// + /// Gets or sets list of sources which were partially discovered (started discover tests, but then discovery aborted) + /// + public IReadOnlyCollection PartiallyDiscoveredSources { get; set; } = new List(); + + /// + /// Gets or sets list of sources which were not discovered at all + /// + public IReadOnlyCollection NotDiscoveredSources { get; set; } = new List(); } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index 16ec2d6c03..013d39ffeb 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -14,8 +14,8 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Host; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - using CommonResources = Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Resources.Resources; - using ObjectModelConstants = Microsoft.VisualStudio.TestPlatform.ObjectModel.Constants; + using CommonResources = Resources.Resources; + using ObjectModelConstants = TestPlatform.ObjectModel.Constants; /// /// Test request sender implementation. @@ -54,7 +54,7 @@ public class TestRequestSender : ITestRequestSender // Must be in sync with the highest supported version in // src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs file. - private int highestSupportedVersion = 5; + private int highestSupportedVersion = 6; private TestHostConnectionInfo connectionInfo; @@ -290,6 +290,24 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve this.channel.Send(message); } + + /// + public void SendDiscoveryAbort() + { + if (this.IsOperationComplete()) + { + EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Operation is already complete. Skip error message."); + return; + } + + if (EqtTrace.IsVerboseEnabled) + { + EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Sending discovery abort."); + } + + this.channel?.Send(this.dataSerializer.SerializeMessage(MessageType.CancelDiscovery)); + } + #endregion #region Execution Protocol @@ -595,7 +613,12 @@ private void OnDiscoveryMessageReceived(ITestDiscoveryEventsHandler2 discoveryEv case MessageType.DiscoveryComplete: var discoveryCompletePayload = this.dataSerializer.DeserializePayload(data); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(discoveryCompletePayload.TotalTests, discoveryCompletePayload.IsAborted); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( + discoveryCompletePayload.TotalTests, + discoveryCompletePayload.IsAborted, + discoveryCompletePayload.FullyDiscoveredSources, + discoveryCompletePayload.PartiallyDiscoveredSources, + discoveryCompletePayload.NotDiscoveredSources); discoveryCompleteEventArgs.Metrics = discoveryCompletePayload.Metrics; discoveryEventsHandler.HandleDiscoveryComplete( discoveryCompleteEventArgs, diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/InProcessProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/InProcessProxyDiscoveryManager.cs index db1baf2d1a..ae18f5d0a1 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/InProcessProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/InProcessProxyDiscoveryManager.cs @@ -95,6 +95,12 @@ public void Abort() Task.Run(() => this.testHostManagerFactory.GetDiscoveryManager().Abort()); } + /// + public void Abort(ITestDiscoveryEventsHandler2 eventHandler) + { + Task.Run(() => this.testHostManagerFactory.GetDiscoveryManager().Abort(eventHandler)); + } + private void InitializeExtensions(IEnumerable sources) { var extensionsFromSource = this.testHostManager.GetTestPlatformExtensions(sources, Enumerable.Empty()); diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index f41394d598..4e85c42804 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel { using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -42,6 +43,20 @@ public ParallelDiscoveryDataAggregator() #endregion + #region Internal Properties + + /// + /// Dictionary which stores source with corresponding discoveryStatus + /// + internal ConcurrentDictionary SourceStatusMap = new ConcurrentDictionary(); + + /// + /// Indicates if discovery complete payload already sent back to IDE + /// + internal bool IsMessageSent { get; set; } + + #endregion + #region Public Methods /// @@ -128,6 +143,50 @@ public void AggregateDiscoveryDataMetrics(IDictionary metrics) } } + /// + /// Aggregate fully discovered sources,coming from different test hosts, into one list + /// + /// Fully discovered source + internal void AggregateTheSourceAsFullyDiscovered(string source) + { + if (source == null || source == string.Empty) return; + + SourceStatusMap[source] = DiscoveryStatus.FullyDiscovered; + } + + /// + /// Aggregate partially discovered sources,coming from different test hosts, into one list + /// + /// Parially discovered source + internal void AggregateTheSourceAsPartiallyDiscovered(string source) + { + if (source == null || source == string.Empty) return; + + SourceStatusMap[source] = DiscoveryStatus.PartiallyDiscovered; + } + + /// + /// Aggregate value indicating if we already sent message to IDE + /// + /// Boolean value if we already sent message to IDE + internal void AggregateIsMessageSent(bool isMessageSent) + { + this.IsMessageSent = this.IsMessageSent || isMessageSent; + } + + /// + /// Returning sources with particular discovery status + /// + /// Status to filter + /// + internal ICollection GetSourcesWithStatus(DiscoveryStatus status) + { + if (SourceStatusMap == null || SourceStatusMap.IsEmpty) return new List(); + + return SourceStatusMap.Where(source => source.Value == status) + .Select(source => source.Key).ToList(); + } + #endregion } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 1552ca924c..8f505ea6e4 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel { using System.Collections.Generic; + using System.Linq; using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities; @@ -33,6 +34,8 @@ internal class ParallelDiscoveryEventsHandler : ITestDiscoveryEventsHandler2 private IRequestData requestData; + private readonly object sendMessageLock = new object(); + public ParallelDiscoveryEventsHandler(IRequestData requestData, IProxyDiscoveryManager proxyDiscoveryManager, ITestDiscoveryEventsHandler2 actualDiscoveryEventsHandler, @@ -70,6 +73,8 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete { ConvertToRawMessageAndSend(MessageType.TestCasesFound, lastChunk); this.HandleDiscoveredTests(lastChunk); + // If we come here it means that some source was already fully discovered so we can mark it + AggregateComingSources(discoveryDataAggregator, lastChunk); } // Aggregate for final discovery complete @@ -88,13 +93,20 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete if (parallelDiscoveryComplete) { + var fullyDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered) as IReadOnlyCollection; + var partiallyDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered) as IReadOnlyCollection; + var notDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered) as IReadOnlyCollection; + // In case of sequential discovery - RawMessage would have contained a 'DiscoveryCompletePayload' object // To send a raw message - we need to create raw message from an aggregated payload object var testDiscoveryCompletePayload = new DiscoveryCompletePayload() { TotalTests = discoveryDataAggregator.TotalTests, - IsAborted = discoveryDataAggregator.IsAborted, - LastDiscoveredTests = null + IsAborted = discoveryDataAggregator.IsAborted, + LastDiscoveredTests = null, + FullyDiscoveredSources = fullyDiscovered, + PartiallyDiscoveredSources = partiallyDiscovered, + NotDiscoveredSources = notDiscovered }; // Collecting Final Discovery State @@ -104,11 +116,15 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete var aggregatedDiscoveryDataMetrics = discoveryDataAggregator.GetAggregatedDiscoveryDataMetrics(); testDiscoveryCompletePayload.Metrics = aggregatedDiscoveryDataMetrics; - // we have to send raw messages as we block the discovery complete actual raw messages - this.ConvertToRawMessageAndSend(MessageType.DiscoveryComplete, testDiscoveryCompletePayload); + // Sending discovery complete message to IDE + this.SendMessage(discoveryDataAggregator, testDiscoveryCompletePayload); var finalDiscoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(this.discoveryDataAggregator.TotalTests, - this.discoveryDataAggregator.IsAborted); + this.discoveryDataAggregator.IsAborted, + fullyDiscovered, + partiallyDiscovered, + notDiscovered); + finalDiscoveryCompleteEventArgs.Metrics = aggregatedDiscoveryDataMetrics; // send actual test discovery complete to clients @@ -160,5 +176,54 @@ private void ConvertToRawMessageAndSend(string messageType, object payload) var rawMessage = this.dataSerializer.SerializePayload(messageType, payload); this.actualDiscoveryEventsHandler.HandleRawMessage(rawMessage); } + + /// + /// Sending discovery complete message to IDE + /// + /// Discovery aggregator to know if we already sent this message + /// Discovery complete payload to send + private void SendMessage(ParallelDiscoveryDataAggregator discoveryDataAggregator, DiscoveryCompletePayload testDiscoveryCompletePayload) + { + // In case of abort scenario, we need to send raw message to IDE only once after abortion. + // All other testhost which will finish after shouldn't send raw message + if (!discoveryDataAggregator.IsMessageSent) + { + lock (sendMessageLock) + { + if (!discoveryDataAggregator.IsMessageSent) + { + // we have to send raw messages as we block the discovery complete actual raw messages + this.ConvertToRawMessageAndSend(MessageType.DiscoveryComplete, testDiscoveryCompletePayload); + discoveryDataAggregator.AggregateIsMessageSent(true); + } + } + } + } + + /// + /// Getting the source name from the last chunk + /// + /// The last test case chunk which was discovered + /// The source of the last test case chunk + private string GetTheSourceFromTheLastChunk(IEnumerable lastChunk) + { + if (lastChunk == null || lastChunk.Count() == 0) return string.Empty; + + var chunk = lastChunk.Last(); + + return chunk.Source; + } + + /// + /// Aggregate source as fully discovered + /// + /// Aggregator to aggregate results + /// Last chunk of discovered test cases + private void AggregateComingSources(ParallelDiscoveryDataAggregator discoveryDataAggregator, IEnumerable lastChunk) + { + string source = GetTheSourceFromTheLastChunk(lastChunk); + + discoveryDataAggregator.AggregateTheSourceAsFullyDiscovered(source); + } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index 6307ea41d3..d52011062c 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -50,6 +50,8 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager private object discoveryStatusLockObject = new object(); + private object enumeratorLockObject = new object(); + #endregion public ParallelProxyDiscoveryManager(IRequestData requestData, Func actualProxyManagerCreator, int parallelLevel, bool sharedHosts) @@ -86,6 +88,13 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve { EqtTrace.Verbose("ParallelProxyDiscoveryManager: Start discovery. Total sources: " + this.availableTestSources); } + + // One data aggregator per parallel discovery + this.currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator(); + + // Marking all sources as not discovered before starting actual discovery + this.MarkAllSourcesAsNotDiscovered(discoveryCriteria.Sources); + this.DiscoverTestsPrivate(eventHandler); } @@ -96,6 +105,14 @@ public void Abort() this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(), doActionsInParallel: true); } + /// + public void Abort(ITestDiscoveryEventsHandler2 eventHandler) + { + this.discoveryAbortRequested = true; + this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(), doActionsInParallel: true); + this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(eventHandler), doActionsInParallel: true); + } + /// public void Close() { @@ -182,9 +199,6 @@ private void DiscoverTestsPrivate(ITestDiscoveryEventsHandler2 discoveryEventsHa // Reset the discovery complete data this.discoveryCompletedClients = 0; - // One data aggregator per parallel discovery - this.currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator(); - foreach (var concurrentManager in this.GetConcurrentManagerInstances()) { var parallelEventsHandler = new ParallelDiscoveryEventsHandler( @@ -257,5 +271,22 @@ private void DiscoverTestsOnConcurrentManager(IProxyDiscoveryManager proxyDiscov EqtTrace.Verbose("ProxyParallelDiscoveryManager: No sources available for discovery."); } } + + /// + /// Mark all sources as not discovered before starting actual discovery + /// + /// Sources which will be discovered + private void MarkAllSourcesAsNotDiscovered(IEnumerable sources) + { + if (sources == null || sources.Count() == 0) return; + + lock (enumeratorLockObject) + { + foreach (string source in sources) + { + this.currentDiscoveryDataAggregator.SourceStatusMap[source] = DiscoveryStatus.NotDiscovered; + } + } + } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs index c8d85fa1b8..785d45779a 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs @@ -196,6 +196,20 @@ public void Abort() this.Close(); } + /// + public void Abort(ITestDiscoveryEventsHandler2 eventHandler) + { + if (this.baseTestDiscoveryEventsHandler == null) + { + this.baseTestDiscoveryEventsHandler = eventHandler; + } + + if (this.isCommunicationEstablished) + { + this.proxyOperationManager.RequestSender.SendDiscoveryAbort(); + } + } + /// public void Close() { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs index f85f70fa65..663a5ec0d5 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs @@ -26,7 +26,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.PlatformAbstractions; using Utilities; - using CrossPlatEngineResources = Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources.Resources; + using CrossPlatEngineResources = Resources.Resources; /// /// Enumerates through all the discoverers. @@ -200,7 +200,7 @@ private void DiscoverTestsFromSingleDiscoverer( ref double totalAdaptersUsed, ref double totalTimeTakenByAdapters) { - if (!DiscovererEnumerator.TryToLoadDiscoverer(discoverer, logger, out var discovererType)) + if (!TryToLoadDiscoverer(discoverer, logger, out var discovererType)) { // Fail to instantiate the discoverer type. return; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index f2751c18e5..322c36f800 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery { using System; + using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; @@ -18,10 +19,11 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Tracing.Interfaces; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - using CrossPlatEngineResources = Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources.Resources; + using CrossPlatEngineResources = Resources.Resources; /// /// Orchestrates discovery operations for the engine communicating with the test host process. @@ -34,6 +36,8 @@ public class DiscoveryManager : IDiscoveryManager private ITestDiscoveryEventsHandler2 testDiscoveryEventsHandler; private DiscoveryCriteria discoveryCriteria; private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); + private string previousSource = null; + private ConcurrentDictionary DiscoveredSourcesWithStatus { get; set; } = new ConcurrentDictionary(); /// /// Initializes a new instance of the class. @@ -104,6 +108,8 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve if (verifiedSources.Any()) { verifiedExtensionSourceMap.Add(kvp.Key, kvp.Value); + // Mark all sources as NotDiscovered before actual discovery starts + MarkSourcesWithStatus(verifiedSources, DiscoveryStatus.NotDiscovered); } } @@ -133,6 +139,9 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve if (lastChunk != null) { UpdateTestCases(lastChunk, this.discoveryCriteria.Package); + /* When discovery is complete we will have case that the last discovered source is still marked as partiallyDiscovered. + * So we need to mark it as fullyDiscovered.*/ + MarkTheLastSourceAsFullyDiscovered(lastChunk); } // Collecting Discovery State @@ -140,10 +149,18 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve // Collecting Total Tests Discovered this.requestData.MetricsCollection.Add(TelemetryDataConstants.TotalTestsDiscovered, totalDiscoveredTestCount); - var discoveryCompleteEventsArgs = new DiscoveryCompleteEventArgs(totalDiscoveredTestCount, false) + + if (cancellationTokenSource.IsCancellationRequested) { - Metrics = this.requestData.MetricsCollection.Metrics - }; + totalDiscoveredTestCount = -1; + } + + var discoveryCompleteEventsArgs = new DiscoveryCompleteEventArgs(totalDiscoveredTestCount, cancellationTokenSource.IsCancellationRequested, + GetFilteredSources(DiscoveryStatus.FullyDiscovered), + GetFilteredSources(DiscoveryStatus.PartiallyDiscovered), + GetFilteredSources(DiscoveryStatus.NotDiscovered)); + + discoveryCompleteEventsArgs.Metrics = this.requestData.MetricsCollection.Metrics; eventHandler.HandleDiscoveryComplete(discoveryCompleteEventsArgs, lastChunk); } @@ -167,6 +184,22 @@ public void Abort() this.cancellationTokenSource.Cancel(); } + /// + public void Abort(ITestDiscoveryEventsHandler2 eventHandler) + { + if (!cancellationTokenSource.IsCancellationRequested) + { + this.Abort(); + } + + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true, + GetFilteredSources(DiscoveryStatus.FullyDiscovered), + GetFilteredSources(DiscoveryStatus.PartiallyDiscovered), + GetFilteredSources(DiscoveryStatus.NotDiscovered)); + + eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, null); + } + private void OnReportTestCases(IEnumerable testCases) { UpdateTestCases(testCases, this.discoveryCriteria.Package); @@ -174,6 +207,8 @@ private void OnReportTestCases(IEnumerable testCases) if (this.testDiscoveryEventsHandler != null) { this.testDiscoveryEventsHandler.HandleDiscoveredTests(testCases); + // We need to mark sources based on already discovered testcases + MarkSourcesBasedOnDiscoveredTestCases(testCases); } else { @@ -293,5 +328,93 @@ private static void UpdateTestCases(IEnumerable testCases, string pack } } } + + /// + /// Mark sources based on already discovered testCases + /// + /// List of testCases which were already discovered + private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCases) + { + if (testCases == null || testCases.Count() == 0) return; + + foreach (var testCase in testCases) + { + string currentSource = testCase.Source; + + // If it is first list of testCases which was discovered, we mark sources as partiallyDiscovered + // Or if current source is the same as previous we mark them as partiallyDiscovered again for consistency + if (previousSource is null || previousSource == currentSource) + { + MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); + } + // If source is changed, we need to mark previous source as already fullyDiscovered + // and currentSource should be partiallyDiscovered + else if (currentSource != previousSource) + { + MarkSourceWithStatus(previousSource, DiscoveryStatus.FullyDiscovered); + MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); + } + + this.previousSource = currentSource; + } + } + + /// + /// Mark the last source as fullyDiscovered + /// + /// Last chunk of testCases which were discovered + private void MarkTheLastSourceAsFullyDiscovered(IList lastChunk) + { + if (lastChunk == null || lastChunk.Count == 0) return; + int size = lastChunk.Count; + var lastTestCase = lastChunk[size - 1]; + string lastSource = lastTestCase.Source; + DiscoveredSourcesWithStatus[lastSource] = DiscoveryStatus.FullyDiscovered; + } + + /// + /// Mark the source with particular DiscoveryStatus + /// + /// Sources to mark + /// DiscoveryStatus to mark for source + private void MarkSourceWithStatus(string source, DiscoveryStatus status) + { + if (source == null) return; + DiscoveredSourcesWithStatus[source] = status; + } + + /// + /// Mark sources with particular DiscoveryStatus + /// + /// List of sources to mark + /// DiscoveryStatus to mark for list of sources + private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus status) + { + if (sources == null || sources.Count() == 0) return; + + foreach (var source in sources) + { + DiscoveredSourcesWithStatus[source] = status; + } + } + + /// + /// Filter discovery sources based on discovery status condition + /// + /// discoveryStatus indicates if source was fully/partially/not discovered + /// + private IReadOnlyCollection GetFilteredSources(DiscoveryStatus discoveryStatus) + { + var discoveredSources = DiscoveredSourcesWithStatus; + + // If by some accident discoveredSources map is empty we will return empty list + if (discoveredSources == null || discoveredSources.Count == 0) + { + return new List(); + } + + return discoveredSources.Where(source => source.Value == discoveryStatus) + .Select(source => source.Key).ToList(); + } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index bbfe0ee0ca..dff7494fdc 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -18,8 +18,8 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using Microsoft.VisualStudio.TestPlatform.Utilities; - using CrossPlatResources = Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Resources.Resources; - using ObjectModelConstants = Microsoft.VisualStudio.TestPlatform.ObjectModel.Constants; + using CrossPlatResources = CrossPlatEngine.Resources.Resources; + using ObjectModelConstants = TestPlatform.ObjectModel.Constants; public class TestRequestHandler : ITestRequestHandler { @@ -27,7 +27,7 @@ public class TestRequestHandler : ITestRequestHandler // Must be in sync with the highest supported version in // src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs file. - private int highestSupportedVersion = 5; + private int highestSupportedVersion = 6; private readonly IDataSerializer dataSerializer; private ITestHostManagerFactory testHostManagerFactory; @@ -204,7 +204,10 @@ public void DiscoveryComplete(DiscoveryCompleteEventArgs discoveryCompleteEventA TotalTests = discoveryCompleteEventArgs.TotalCount, LastDiscoveredTests = discoveryCompleteEventArgs.IsAborted ? null : lastChunk, IsAborted = discoveryCompleteEventArgs.IsAborted, - Metrics = discoveryCompleteEventArgs.Metrics + Metrics = discoveryCompleteEventArgs.Metrics, + FullyDiscoveredSources = discoveryCompleteEventArgs.FullyDiscoveredSources, + PartiallyDiscoveredSources = discoveryCompleteEventArgs.PartiallyDiscoveredSources, + NotDiscoveredSources = discoveryCompleteEventArgs.NotDiscoveredSources }, this.protocolVersion); this.SendData(data); @@ -485,6 +488,12 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec this.onAttachDebuggerAckRecieved?.Invoke(message); break; + case MessageType.CancelDiscovery: + jobQueue.Pause(); + this.testHostManagerFactoryReady.Wait(); + testHostManagerFactory.GetDiscoveryManager().Abort(new TestDiscoveryEventHandler(this)); + break; + case MessageType.AbortTestRun: try { diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs index a17323a347..caaf2bfdef 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs @@ -12,6 +12,24 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Client /// public class DiscoveryCompleteEventArgs : EventArgs { + /// + /// Constructor for creating event args object + /// + /// Total tests which got discovered + /// Specifies if discovery has been aborted. + /// List of fully discovered sources + /// List of partially discovered sources + /// List of not discovered sources + public DiscoveryCompleteEventArgs(long totalTests, bool isAborted, + IReadOnlyCollection fullyDiscoveredSources, + IReadOnlyCollection partiallyDiscoveredSources, + IReadOnlyCollection notDiscoveredSources) : this(totalTests, isAborted) + { + FullyDiscoveredSources = fullyDiscoveredSources; + PartiallyDiscoveredSources = partiallyDiscoveredSources; + NotDiscoveredSources = notDiscoveredSources; + } + /// /// Constructor for creating event args object /// @@ -42,5 +60,20 @@ public DiscoveryCompleteEventArgs(long totalTests, bool isAborted) /// Metrics /// public IDictionary Metrics { get; set; } + + /// + /// Gets list of sources which were fully discovered + /// + public IReadOnlyCollection FullyDiscoveredSources { get; } = new List(); + + /// + /// Gets list of sources which were partially discovered (started discover tests, but then discovery aborted) + /// + public IReadOnlyCollection PartiallyDiscoveredSources { get; } = new List(); + + /// + /// Gets list of sources which were not discovered at all + /// + public IReadOnlyCollection NotDiscoveredSources { get; } = new List(); } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs index ce3ab28efc..9b01a3bc16 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs @@ -49,5 +49,10 @@ DiscoveryCriteria DiscoveryCriteria /// Aborts the discovery request /// void Abort(); + + /// + /// Aborts the discovery request with event handler + /// + void AbortWithEventHandler(); } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Constants.cs b/src/Microsoft.TestPlatform.ObjectModel/Constants.cs index 8b1d57bbb8..c34a572bb6 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Constants.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Constants.cs @@ -173,13 +173,18 @@ public static class Constants /// /// The default protocol version /// - public static readonly ProtocolConfig DefaultProtocolConfig = new ProtocolConfig { Version = 5 }; + public static readonly ProtocolConfig DefaultProtocolConfig = new ProtocolConfig { Version = 6 }; /// /// The minimum protocol version that has debug support /// public const int MinimumProtocolVersionWithDebugSupport = 3; + /// + /// The minimum protocol version that has debug support + /// + public const int MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport = 6; + /// /// Name of the results directory /// diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index be26f63f1f..f621885063 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -22,7 +22,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; - using TranslationLayerResources = Microsoft.VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Resources.Resources; + using TranslationLayerResources = VisualStudio.TestPlatform.VsTestConsole.TranslationLayer.Resources.Resources; /// /// Vstest console request sender for sending requests to vstest.console.exe @@ -43,7 +43,7 @@ internal class VsTestConsoleRequestSender : ITranslationLayerRequestSender private bool handShakeSuccessful = false; - private int protocolVersion = 5; + private int protocolVersion = 6; /// /// Used to cancel blocking tasks associated with the vstest.console process. @@ -1025,7 +1025,10 @@ private void SendMessageAndListenAndReportTestCases( var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( discoveryCompletePayload.TotalTests, - discoveryCompletePayload.IsAborted); + discoveryCompletePayload.IsAborted, + discoveryCompletePayload.FullyDiscoveredSources, + discoveryCompletePayload.PartiallyDiscoveredSources, + discoveryCompletePayload.NotDiscoveredSources); // Adding metrics from vstest.console. discoveryCompleteEventArgs.Metrics = discoveryCompletePayload.Metrics; @@ -1051,7 +1054,7 @@ private void SendMessageAndListenAndReportTestCases( eventHandler.HandleLogMessage( TestMessageLevel.Error, TranslationLayerResources.AbortedTestsDiscovery); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true, new List(), new List(), new List()); eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, null); // Earlier we were closing the connection with vstest.console in case of exceptions. @@ -1115,7 +1118,10 @@ private async Task SendMessageAndListenAndReportTestCasesAsync( var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( discoveryCompletePayload.TotalTests, - discoveryCompletePayload.IsAborted); + discoveryCompletePayload.IsAborted, + discoveryCompletePayload.FullyDiscoveredSources, + discoveryCompletePayload.PartiallyDiscoveredSources, + discoveryCompletePayload.NotDiscoveredSources); // Adding Metrics from VsTestConsole discoveryCompleteEventArgs.Metrics = discoveryCompletePayload.Metrics; @@ -1143,7 +1149,7 @@ private async Task SendMessageAndListenAndReportTestCasesAsync( TestMessageLevel.Error, TranslationLayerResources.AbortedTestsDiscovery); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(-1, true, new List(), new List(), new List()); eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, null); // Earlier we were closing the connection with vstest.console in case of exceptions. diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs index 3b80962f7b..36a9d4aada 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs @@ -99,6 +99,17 @@ public void AbortIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbort() this.discoveryManager.Verify(dm => dm.Abort(), Times.Once); } + [TestMethod] + public void AbortWithEventHandlerIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbortWithEventHandler() + { + // Just to set the IsDiscoveryInProgress flag + this.discoveryRequest.DiscoverAsync(); + var eventsHandler = this.discoveryRequest as ITestDiscoveryEventsHandler2; + + this.discoveryRequest.AbortWithEventHandler(); + this.discoveryManager.Verify(dm => dm.Abort(eventsHandler), Times.Once); + } + [TestMethod] public void AbortIfDiscoveryIsNotInProgressShouldNotCallDiscoveryManagerAbort() { From 3e0a4b1ed31193ec72b7b70ac70de64053dc7a29 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Tue, 23 Nov 2021 00:48:28 +0100 Subject: [PATCH 02/31] temp --- .../Discovery/DiscoveryRequest.cs | 4 +++ .../TestRequestSender.cs | 10 +++++++ .../ParallelDiscoveryEventsHandler.cs | 21 ++++++++----- .../Parallel/ParallelProxyDiscoveryManager.cs | 1 - .../Client/ProxyDiscoveryManager.cs | 1 - .../Discovery/DiscoveryManager.cs | 3 ++ .../EventHandlers/TestRequestHandler.cs | 3 ++ .../PublicAPI/PublicAPI.Unshipped.txt | 6 ++++ .../VsTestConsoleRequestSender.cs | 4 +++ .../TestPlatformHelpers/TestRequestManager.cs | 7 +++++ .../TranslationLayerTests/DiscoverTests.cs | 22 +++++++++++++- .../EventHandler/DiscoveryEventHandler.cs | 4 +++ .../DesignMode/DesignModeClientTests.cs | 4 +-- .../VsTestConsoleRequestSenderTests.cs | 2 +- .../TestRequestManagerTests.cs | 30 +++++++++---------- 15 files changed, 94 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index c37c26f96f..b3dd5e6388 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Threading; @@ -160,6 +161,9 @@ public void AbortWithEventHandler() if (this.discoveryInProgress) { + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + // Using DiscoveryRequest.HandleDiscoveryComplete eventHandler this.DiscoveryManager.Abort(this); } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index 013d39ffeb..300c8f45d5 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Globalization; using System.Threading; using CoreUtilities.Helpers; @@ -305,6 +306,15 @@ public void SendDiscoveryAbort() EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Sending discovery abort."); } + if (!Debugger.IsAttached) + { + Debugger.Launch(); + } + else + { + Debugger.Break(); + } + this.channel?.Send(this.dataSerializer.SerializeMessage(MessageType.CancelDiscovery)); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 8f505ea6e4..9fd4c15832 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel { using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; @@ -66,6 +67,15 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete var totalTests = discoveryCompleteEventArgs.TotalCount; var isAborted = discoveryCompleteEventArgs.IsAborted; + // Aggregate for final discovery complete + discoveryDataAggregator.Aggregate(totalTests, isAborted); + + // Aggregate Discovery Data Metrics + discoveryDataAggregator.AggregateDiscoveryDataMetrics(discoveryCompleteEventArgs.Metrics); + + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + // we get discovery complete events from each host process // so we cannot "complete" the actual operation until all sources are consumed // We should not block last chunk results while we aggregate overall discovery data @@ -74,15 +84,12 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete ConvertToRawMessageAndSend(MessageType.TestCasesFound, lastChunk); this.HandleDiscoveredTests(lastChunk); // If we come here it means that some source was already fully discovered so we can mark it - AggregateComingSources(discoveryDataAggregator, lastChunk); + if (!discoveryDataAggregator.IsAborted) + { + AggregateComingSources(discoveryDataAggregator, lastChunk); + } } - // Aggregate for final discovery complete - discoveryDataAggregator.Aggregate(totalTests, isAborted); - - // Aggregate Discovery Data Metrics - discoveryDataAggregator.AggregateDiscoveryDataMetrics(discoveryCompleteEventArgs.Metrics); - // Do not send TestDiscoveryComplete to actual test discovery handler // We need to see if there are still sources left - let the parallel manager decide var parallelDiscoveryComplete = this.parallelProxyDiscoveryManager.HandlePartialDiscoveryComplete( diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index d52011062c..d2987591fe 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -109,7 +109,6 @@ public void Abort() public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { this.discoveryAbortRequested = true; - this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(), doActionsInParallel: true); this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(eventHandler), doActionsInParallel: true); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs index 785d45779a..3e81899d49 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs @@ -6,7 +6,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client using System; using System.Collections.Generic; using System.Linq; - using System.Threading; using Microsoft.VisualStudio.TestPlatform.Common; using Microsoft.VisualStudio.TestPlatform.Common.ExtensionFramework; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 322c36f800..05c44936c5 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -187,6 +187,9 @@ public void Abort() /// public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + if (!cancellationTokenSource.IsCancellationRequested) { this.Abort(); diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index dff7494fdc..3e1db0ac83 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -5,6 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Threading; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.EventHandlers; @@ -489,6 +490,8 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec break; case MessageType.CancelDiscovery: + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); jobQueue.Pause(); this.testHostManagerFactoryReady.Wait(); testHostManagerFactory.GetDiscoveryManager().Abort(new TestDiscoveryEventHandler(this)); diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt index e3d7f85f98..f7c6ee6bdd 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt @@ -4,3 +4,9 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.TestSes Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryRequestPayload.TestSessionInfo.get -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryRequestPayload.TestSessionInfo.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestPlatform.StartTestSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IRequestData requestData, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StartTestSessionCriteria criteria, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler eventsHandler) -> bool +const Microsoft.VisualStudio.TestPlatform.ObjectModel.Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport = 6 -> int +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.DiscoveryCompleteEventArgs(long totalTests, bool isAborted, System.Collections.Generic.IReadOnlyCollection fullyDiscoveredSources, System.Collections.Generic.IReadOnlyCollection partiallyDiscoveredSources, System.Collections.Generic.IReadOnlyCollection notDiscoveredSources) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IDiscoveryRequest.AbortWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index f621885063..c998ab6c40 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -5,6 +5,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Net; using System.Threading; @@ -1019,6 +1020,9 @@ private void SendMessageAndListenAndReportTestCases( "VsTestConsoleRequestSender.SendMessageAndListenAndReportTestCases: Discovery complete."); } + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + var discoveryCompletePayload = this.dataSerializer .DeserializePayload(message); diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index c450e968c9..1ca2d84927 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -529,6 +529,13 @@ public void CancelDiscovery() this.currentDiscoveryRequest?.Abort(); } + /// + public void CancelDiscoveryWithEventHandler() + { + EqtTrace.Info("TestRequestManager.CancelDiscoveryWithEventHandler: Sending cancel request."); + this.currentDiscoveryRequest?.AbortWithEventHandler(); + } + /// public void AbortTestRun() { diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs index 35dfc4181d..638fd1af71 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. + +// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace Microsoft.TestPlatform.AcceptanceTests.TranslationLayerTests @@ -143,6 +144,25 @@ public void DiscoverTestsUsingEventHandler1AndBatchSize(RunnerInfo runnerInfo) Assert.AreEqual(3, discoveryEventHandlerForBatchSize.BatchSize); } + [TestMethod] + [NetCoreTargetFrameworkDataSource] + [NetFullTargetFrameworkDataSource] + public void DisoverTestUsingEventHandler2ShouldContainAllSourcesAsFullyDiscovered(RunnerInfo runnerInfo) + { + SetTestEnvironment(this.testEnvironment, runnerInfo); + this.Setup(); + + var eventHandler2 = new DiscoveryEventHandler2(); + + this.vstestConsoleWrapper.DiscoverTests(GetTestAssemblies(), + this.GetDefaultRunSettings(), + null, + eventHandler2); + + // Assert. + Assert.AreEqual(2, eventHandler2.FullyDiscoveredSources.Count); + } + [TestMethod] [NetFullTargetFrameworkDataSource] [NetCoreTargetFrameworkDataSource] diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs index e6e72e7a24..733c5dd2c4 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs @@ -70,6 +70,10 @@ public class DiscoveryEventHandler2 : ITestDiscoveryEventsHandler2 /// public List DiscoveredTestCases { get; } + public IReadOnlyCollection FullyDiscoveredSources { get; private set; } + public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } + public IReadOnlyCollection NotDiscoveredSources { get; private set; } + public List testMessages; /// diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs index 9cf49fb843..acdc7a0a99 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/DesignMode/DesignModeClientTests.cs @@ -41,7 +41,7 @@ public class DesignModeClientTests private readonly DesignModeClient designModeClient; - private readonly int protocolVersion = 5; + private readonly int protocolVersion = 6; private readonly AutoResetEvent completeEvent; @@ -134,7 +134,7 @@ public void DesignModeClientConnectShouldNotSendConnectedIfServerConnectionTimes [TestMethod] public void DesignModeClientDuringConnectShouldHighestCommonVersionWhenReceivedVersionIsGreaterThanSupportedVersion() { - var verCheck = new Message { MessageType = MessageType.VersionCheck, Payload = 5 }; + var verCheck = new Message { MessageType = MessageType.VersionCheck, Payload = 6 }; var sessionEnd = new Message { MessageType = MessageType.SessionEnd }; this.mockCommunicationManager.Setup(cm => cm.WaitForServerConnection(It.IsAny())).Returns(true); this.mockCommunicationManager.SetupSequence(cm => cm.ReceiveMessage()).Returns(verCheck).Returns(sessionEnd); diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs index c07b2698b8..202b60a0c6 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs @@ -38,7 +38,7 @@ public class VsTestConsoleRequestSenderTests private readonly int WaitTimeout = 2000; - private int protocolVersion = 5; + private int protocolVersion = 6; private IDataSerializer serializer = JsonDataSerializer.Instance; public VsTestConsoleRequestSenderTests() diff --git a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs index d8440633b5..cf1bfb541b 100644 --- a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs +++ b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs @@ -236,7 +236,7 @@ public void DiscoverTestsShouldPassSameProtocolConfigInRequestData() RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6 }; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); @@ -260,7 +260,7 @@ public void DiscoverTestsShouldPassSameProtocolConfigInRequestData() this.testRequestManager.DiscoverTests(payload, mockDiscoveryRegistrar.Object, mockProtocolConfig); // Verify. - Assert.AreEqual(5, actualRequestData.ProtocolConfig.Version); + Assert.AreEqual(6, actualRequestData.ProtocolConfig.Version); } @@ -286,7 +286,7 @@ public void DiscoverTestsShouldCollectMetrics() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -335,7 +335,7 @@ public void DiscoverTestsShouldCollectTargetDeviceLocalMachineIfTargetDeviceStri " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6 }; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -378,7 +378,7 @@ public void DiscoverTestsShouldCollectTargetDeviceIfTargetDeviceIsDevice() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -421,7 +421,7 @@ public void DiscoverTestsShouldCollectTargetDeviceIfTargetDeviceIsEmulator() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -464,7 +464,7 @@ public void DiscoverTestsShouldCollectCommands() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -519,7 +519,7 @@ public void DiscoverTestsShouldCollectTestSettings() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -566,7 +566,7 @@ public void DiscoverTestsShouldCollectVsmdiFile() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -613,7 +613,7 @@ public void DiscoverTestsShouldCollectTestRunConfigFile() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; var mockDiscoveryRegistrar = new Mock(); IRequestData actualRequestData = null; @@ -907,7 +907,7 @@ public void RunTestsShouldPassSameProtocolConfigInRequestData() Sources = new List() { "a" }, RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -934,7 +934,7 @@ public void RunTestsShouldCollectCommands() Sources = new List() { "a" }, RunSettings = DefaultRunsettings }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1001,7 +1001,7 @@ public void RunTestsShouldCollectTelemetryForLegacySettings() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1051,7 +1051,7 @@ public void RunTestsShouldCollectTelemetryForTestSettingsEmbeddedInsideRunSettin " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( @@ -1099,7 +1099,7 @@ public void RunTestsShouldCollectMetrics() " }; - var mockProtocolConfig = new ProtocolConfig { Version = 5 }; + var mockProtocolConfig = new ProtocolConfig { Version = 6}; IRequestData actualRequestData = null; var mockDiscoveryRequest = new Mock(); this.mockTestPlatform.Setup(mt => mt.CreateTestRunRequest(It.IsAny(), It.IsAny(), It.IsAny())).Callback( From d114afb51a0c5e1ebceda4322ac35059fe801806 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Tue, 23 Nov 2021 01:37:12 +0100 Subject: [PATCH 03/31] initila --- .../Discovery/DiscoveryRequest.cs | 3 --- .../TestRequestSender.cs | 9 --------- .../Client/Parallel/ParallelDiscoveryEventsHandler.cs | 3 --- .../Discovery/DiscoveryManager.cs | 3 --- .../EventHandlers/TestRequestHandler.cs | 2 -- .../VsTestConsoleRequestSender.cs | 3 --- 6 files changed, 23 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index b3dd5e6388..dc25f0f533 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -161,9 +161,6 @@ public void AbortWithEventHandler() if (this.discoveryInProgress) { - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - // Using DiscoveryRequest.HandleDiscoveryComplete eventHandler this.DiscoveryManager.Abort(this); } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index 300c8f45d5..2a9baf1616 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -306,15 +306,6 @@ public void SendDiscoveryAbort() EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Sending discovery abort."); } - if (!Debugger.IsAttached) - { - Debugger.Launch(); - } - else - { - Debugger.Break(); - } - this.channel?.Send(this.dataSerializer.SerializeMessage(MessageType.CancelDiscovery)); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 9fd4c15832..fbbf9359ec 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -73,9 +73,6 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete // Aggregate Discovery Data Metrics discoveryDataAggregator.AggregateDiscoveryDataMetrics(discoveryCompleteEventArgs.Metrics); - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - // we get discovery complete events from each host process // so we cannot "complete" the actual operation until all sources are consumed // We should not block last chunk results while we aggregate overall discovery data diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 05c44936c5..322c36f800 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -187,9 +187,6 @@ public void Abort() /// public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - if (!cancellationTokenSource.IsCancellationRequested) { this.Abort(); diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 3e1db0ac83..9f1f8b31e5 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -490,8 +490,6 @@ public void OnMessageReceived(object sender, MessageReceivedEventArgs messageRec break; case MessageType.CancelDiscovery: - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); jobQueue.Pause(); this.testHostManagerFactoryReady.Wait(); testHostManagerFactory.GetDiscoveryManager().Abort(new TestDiscoveryEventHandler(this)); diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index c998ab6c40..68fd6db170 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -1020,9 +1020,6 @@ private void SendMessageAndListenAndReportTestCases( "VsTestConsoleRequestSender.SendMessageAndListenAndReportTestCases: Discovery complete."); } - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - var discoveryCompletePayload = this.dataSerializer .DeserializePayload(message); From 9bc76c7021100f26311436d3455343f7cac5801a Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Tue, 23 Nov 2021 17:09:38 +0100 Subject: [PATCH 04/31] Stopping discovery after abort --- .../Client/Parallel/ParallelProxyDiscoveryManager.cs | 7 +------ .../VsTestConsoleRequestSender.cs | 1 - .../TestPlatformHelpers/TestRequestManagerTests.cs | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index d2987591fe..2afa687167 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -38,9 +38,6 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager public void Abort() { - this.discoveryAbortRequested = true; this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(), doActionsInParallel: true); } /// public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { - this.discoveryAbortRequested = true; this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(eventHandler), doActionsInParallel: true); } @@ -147,7 +142,7 @@ If discovery is complete or discovery aborting was requsted by testPlatfrom(user when testhost crashed by itself and when user requested it (f.e. through TW) Schedule the clean up for managers and handlers. */ - if (allDiscoverersCompleted || discoveryAbortRequested) + if (allDiscoverersCompleted || isAborted) { // Reset enumerators this.sourceEnumerator = null; diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index 68fd6db170..f621885063 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -5,7 +5,6 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Linq; using System.Net; using System.Threading; diff --git a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs index cf1bfb541b..a3449ae2af 100644 --- a/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs +++ b/test/vstest.console.UnitTests/TestPlatformHelpers/TestRequestManagerTests.cs @@ -920,7 +920,7 @@ public void RunTestsShouldPassSameProtocolConfigInRequestData() this.testRequestManager.RunTests(payload, new Mock().Object, new Mock().Object, mockProtocolConfig); // Verify. - Assert.AreEqual(5, actualRequestData.ProtocolConfig.Version); + Assert.AreEqual(6, actualRequestData.ProtocolConfig.Version); } [TestMethod] From 5f6ba4859ef27196999f6c598e24db2b79c09f6d Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Tue, 23 Nov 2021 20:36:10 +0100 Subject: [PATCH 05/31] removing old logic test --- .../Discovery/DiscoveryRequest.cs | 1 - .../ParallelDiscoveryEventsHandler.cs | 1 - .../EventHandlers/TestRequestHandler.cs | 1 - .../ParallelProxyDiscoveryManagerTests.cs | 21 ------------------- 4 files changed, 24 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index dc25f0f533..c37c26f96f 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Linq; using System.Threading; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index fbbf9359ec..01bbdbe330 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -4,7 +4,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel { using System.Collections.Generic; - using System.Diagnostics; using System.Linq; using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs index 9f1f8b31e5..dff7494fdc 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/EventHandlers/TestRequestHandler.cs @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Threading; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.EventHandlers; diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs index d9f85b420b..c6ac890213 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs @@ -101,27 +101,6 @@ public void DiscoverTestsShouldProcessAllSources() AssertMissingAndDuplicateSources(processedSources); } - /// - /// Create ParallelProxyDiscoveryManager with parallel level 1 and two source, - /// Abort in any source should not stop discovery for other sources. - /// - [TestMethod] - public void DiscoveryTestsShouldProcessAllSourcesOnDiscoveryAbortsForAnySource() - { - // Since the hosts are aborted, total aggregated tests sent across will be -1 - var discoveryManagerMock = new Mock(); - this.createdMockManagers.Add(discoveryManagerMock); - var parallelDiscoveryManager = this.SetupDiscoveryManager(() => discoveryManagerMock.Object, 1, true, totalTests: -1); - - Task.Run(() => - { - parallelDiscoveryManager.DiscoverTests(this.testDiscoveryCriteria, this.mockHandler.Object); - }); - - Assert.IsTrue(this.discoveryCompleted.Wait(ParallelProxyDiscoveryManagerTests.taskTimeout), "Test discovery not completed."); - Assert.AreEqual(2, processedSources.Count, "All Sources must be processed."); - } - /// /// Create ParallelProxyDiscoveryManager with parallel level 1 and two sources, /// Overall discovery should stop, if aborting was requested From a239149d87799632ca0680de0b1a0c3a5435690a Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Tue, 23 Nov 2021 22:22:04 +0100 Subject: [PATCH 06/31] Fixing test --- .../EventHandler/DiscoveryEventHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs index 733c5dd2c4..5dc42269de 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs @@ -70,9 +70,9 @@ public class DiscoveryEventHandler2 : ITestDiscoveryEventsHandler2 /// public List DiscoveredTestCases { get; } - public IReadOnlyCollection FullyDiscoveredSources { get; private set; } - public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } - public IReadOnlyCollection NotDiscoveredSources { get; private set; } + public IReadOnlyCollection FullyDiscoveredSources { get; private set; } = new List(); + public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } = new List(); + public IReadOnlyCollection NotDiscoveredSources { get; private set; } = new List(); public List testMessages; From fcdd4b6f2666b337efea86f890414ec9384f7ec7 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Wed, 24 Nov 2021 15:28:28 +0100 Subject: [PATCH 07/31] fixing last chunk logic --- .../IParallelProxyDiscoveryManager.cs | 5 +++++ .../ParallelDiscoveryEventsHandler.cs | 7 +++++++ .../Parallel/ParallelProxyDiscoveryManager.cs | 6 +++++- .../Discovery/DiscoveryManager.cs | 12 +++++------ .../EventHandler/DiscoveryEventHandler.cs | 9 +++++--- .../ParallelProxyDiscoveryManagerTests.cs | 21 +++++++++++++++++++ 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs index 467ea8a990..39d6db13ec 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs @@ -10,6 +10,11 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine /// public interface IParallelProxyDiscoveryManager : IParallelOperationManager, IProxyDiscoveryManager { + /// + /// Indicates if user requested an abortion + /// + bool IsAbortRequested { get; set; } + /// /// Handles Partial Discovery Complete event coming from a specific concurrent proxy discovery manager /// Each concurrent proxy discovery manager will signal the parallel discovery manager when its complete diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 01bbdbe330..9e58ca58a4 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -100,6 +100,13 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete var partiallyDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered) as IReadOnlyCollection; var notDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered) as IReadOnlyCollection; + // If parallel discovery completed because of abortion + // we need to set isAborted to true and totalTests = -1 + if (this.parallelProxyDiscoveryManager.IsAbortRequested) + { + discoveryDataAggregator.Aggregate(-1, true); + } + // In case of sequential discovery - RawMessage would have contained a 'DiscoveryCompletePayload' object // To send a raw message - we need to create raw message from an aggregated payload object var testDiscoveryCompletePayload = new DiscoveryCompletePayload() diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index 2afa687167..0f68315365 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -38,6 +38,8 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager public void Abort() { + IsAbortRequested = true; this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(), doActionsInParallel: true); } /// public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { + IsAbortRequested = true; this.DoActionOnAllManagers((proxyManager) => proxyManager.Abort(eventHandler), doActionsInParallel: true); } @@ -142,7 +146,7 @@ If discovery is complete or discovery aborting was requsted by testPlatfrom(user when testhost crashed by itself and when user requested it (f.e. through TW) Schedule the clean up for managers and handlers. */ - if (allDiscoverersCompleted || isAborted) + if (allDiscoverersCompleted || IsAbortRequested) { // Reset enumerators this.sourceEnumerator = null; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 322c36f800..94b042fbf2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -141,7 +141,7 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve UpdateTestCases(lastChunk, this.discoveryCriteria.Package); /* When discovery is complete we will have case that the last discovered source is still marked as partiallyDiscovered. * So we need to mark it as fullyDiscovered.*/ - MarkTheLastSourceAsFullyDiscovered(lastChunk); + MarkTheLastChunkSourcesAsFullyDiscovered(lastChunk); } // Collecting Discovery State @@ -363,13 +363,13 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Mark the last source as fullyDiscovered /// /// Last chunk of testCases which were discovered - private void MarkTheLastSourceAsFullyDiscovered(IList lastChunk) + private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) { if (lastChunk == null || lastChunk.Count == 0) return; - int size = lastChunk.Count; - var lastTestCase = lastChunk[size - 1]; - string lastSource = lastTestCase.Source; - DiscoveredSourcesWithStatus[lastSource] = DiscoveryStatus.FullyDiscovered; + + var lastChunkSources = lastChunk.Select(testcase => testcase.Source); + + MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } /// diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs index 5dc42269de..9afb7e5f64 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs @@ -70,9 +70,9 @@ public class DiscoveryEventHandler2 : ITestDiscoveryEventsHandler2 /// public List DiscoveredTestCases { get; } - public IReadOnlyCollection FullyDiscoveredSources { get; private set; } = new List(); - public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } = new List(); - public IReadOnlyCollection NotDiscoveredSources { get; private set; } = new List(); + public IReadOnlyCollection FullyDiscoveredSources { get; private set; } + public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } + public IReadOnlyCollection NotDiscoveredSources { get; private set; } public List testMessages; @@ -105,6 +105,9 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete } this.Metrics = discoveryCompleteEventArgs.Metrics; + this.FullyDiscoveredSources = discoveryCompleteEventArgs.FullyDiscoveredSources; + this.PartiallyDiscoveredSources = discoveryCompleteEventArgs.PartiallyDiscoveredSources; + this.NotDiscoveredSources = discoveryCompleteEventArgs.NotDiscoveredSources; } public void HandleDiscoveredTests(IEnumerable discoveredTestCases) diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs index c6ac890213..d9f85b420b 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs @@ -101,6 +101,27 @@ public void DiscoverTestsShouldProcessAllSources() AssertMissingAndDuplicateSources(processedSources); } + /// + /// Create ParallelProxyDiscoveryManager with parallel level 1 and two source, + /// Abort in any source should not stop discovery for other sources. + /// + [TestMethod] + public void DiscoveryTestsShouldProcessAllSourcesOnDiscoveryAbortsForAnySource() + { + // Since the hosts are aborted, total aggregated tests sent across will be -1 + var discoveryManagerMock = new Mock(); + this.createdMockManagers.Add(discoveryManagerMock); + var parallelDiscoveryManager = this.SetupDiscoveryManager(() => discoveryManagerMock.Object, 1, true, totalTests: -1); + + Task.Run(() => + { + parallelDiscoveryManager.DiscoverTests(this.testDiscoveryCriteria, this.mockHandler.Object); + }); + + Assert.IsTrue(this.discoveryCompleted.Wait(ParallelProxyDiscoveryManagerTests.taskTimeout), "Test discovery not completed."); + Assert.AreEqual(2, processedSources.Count, "All Sources must be processed."); + } + /// /// Create ParallelProxyDiscoveryManager with parallel level 1 and two sources, /// Overall discovery should stop, if aborting was requested From 524448b1f22338a0f5c8ce935a48820c785ca3d2 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Thu, 25 Nov 2021 12:41:07 +0100 Subject: [PATCH 08/31] temp commit --- .../Parallel/ParallelDiscoveryDataAggregator.cs | 11 ----------- .../Discovery/DiscoveryManager.cs | 5 ++++- .../VsTestConsoleRequestSender.cs | 4 ++++ 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index 4e85c42804..cc1adbbcd1 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -154,17 +154,6 @@ internal void AggregateTheSourceAsFullyDiscovered(string source) SourceStatusMap[source] = DiscoveryStatus.FullyDiscovered; } - /// - /// Aggregate partially discovered sources,coming from different test hosts, into one list - /// - /// Parially discovered source - internal void AggregateTheSourceAsPartiallyDiscovered(string source) - { - if (source == null || source == string.Empty) return; - - SourceStatusMap[source] = DiscoveryStatus.PartiallyDiscovered; - } - /// /// Aggregate value indicating if we already sent message to IDE /// diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 94b042fbf2..205816f128 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -138,6 +138,9 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve { if (lastChunk != null) { + if (!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + UpdateTestCases(lastChunk, this.discoveryCriteria.Package); /* When discovery is complete we will have case that the last discovered source is still marked as partiallyDiscovered. * So we need to mark it as fullyDiscovered.*/ @@ -360,7 +363,7 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas } /// - /// Mark the last source as fullyDiscovered + /// Mark the last sources as fullyDiscovered /// /// Last chunk of testCases which were discovered private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index f621885063..a50933508b 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -5,6 +5,7 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Net; using System.Threading; @@ -1023,6 +1024,9 @@ private void SendMessageAndListenAndReportTestCases( this.dataSerializer .DeserializePayload(message); + if(!Debugger.IsAttached) Debugger.Launch(); + else Debugger.Break(); + var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( discoveryCompletePayload.TotalTests, discoveryCompletePayload.IsAborted, From 059181e5cf2f96669e57b0669aaec7f31f18a72f Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Fri, 26 Nov 2021 18:41:00 +0100 Subject: [PATCH 09/31] Fixing last chunk is empty case. Some refactoring --- .../Discovery/DiscoveryRequest.cs | 1 - .../RequestHelper/ITestRequestManager.cs | 2 +- .../IParallelProxyDiscoveryManager.cs | 6 +-- .../TestRequestSender.cs | 1 - .../ParallelDiscoveryDataAggregator.cs | 30 +++++++---- .../ParallelDiscoveryEventsHandler.cs | 45 ++++++++-------- .../Parallel/ParallelProxyDiscoveryManager.cs | 2 +- .../Client/ProxyDiscoveryManager.cs | 6 +++ .../Discovery/DiscoveryManager.cs | 52 +++++++++++++------ .../Events/DiscoveryCompleteEventArgs.cs | 6 +-- .../VsTestConsoleRequestSender.cs | 4 -- .../TestPlatformHelpers/TestRequestManager.cs | 2 +- 12 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index c37c26f96f..9d58199b36 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -160,7 +160,6 @@ public void AbortWithEventHandler() if (this.discoveryInProgress) { - // Using DiscoveryRequest.HandleDiscoveryComplete eventHandler this.DiscoveryManager.Abort(this); } else diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index de8ffe1fde..11bad6a82d 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -103,7 +103,7 @@ void StartTestSession( void CancelDiscovery(); /// - /// Cancels the current discovery request with discovery complete event handle + /// Cancels the current discovery request with discovery complete event handler /// void CancelDiscoveryWithEventHandler(); diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs index 39d6db13ec..3157d8216a 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs @@ -36,8 +36,8 @@ bool HandlePartialDiscoveryComplete( /// public enum DiscoveryStatus { - FullyDiscovered, // FullyDiscovered means that source was fully discovered - PartiallyDiscovered, // PartiallyDiscovered means that we started discovery of the source but smth happened (cancel/abort) and we stop processing it - NotDiscovered // Sources which were not touched during discovery + FullyDiscovered, // Indicates that source was fully discovered + PartiallyDiscovered, // Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it + NotDiscovered // Indicates the sources which were not touched during discovery } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index 2a9baf1616..013d39ffeb 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CommunicationUtilities { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Globalization; using System.Threading; using CoreUtilities.Helpers; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index cc1adbbcd1..770c666bcc 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -4,6 +4,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel { using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; + using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using System; using System.Collections.Concurrent; @@ -48,7 +49,7 @@ public ParallelDiscoveryDataAggregator() /// /// Dictionary which stores source with corresponding discoveryStatus /// - internal ConcurrentDictionary SourceStatusMap = new ConcurrentDictionary(); + internal ConcurrentDictionary SourcesWithDiscoveryStatus = new ConcurrentDictionary(); /// /// Indicates if discovery complete payload already sent back to IDE @@ -144,18 +145,29 @@ public void AggregateDiscoveryDataMetrics(IDictionary metrics) } /// - /// Aggregate fully discovered sources,coming from different test hosts, into one list + /// Aggregate the source as fully discovered /// /// Fully discovered source - internal void AggregateTheSourceAsFullyDiscovered(string source) + internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources, DiscoveryStatus status) { - if (source == null || source == string.Empty) return; + if (sources == null || sources.Count() == 0) return; - SourceStatusMap[source] = DiscoveryStatus.FullyDiscovered; + foreach (var source in sources) + { + if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + { + EqtTrace.Warning($"ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus : " + + $"{source} is not present in SourcesWithDiscoveryStatus dictionary"); + } + else + { + SourcesWithDiscoveryStatus[source] = status; + } + } } /// - /// Aggregate value indicating if we already sent message to IDE + /// Aggregate the value indicating if we already sent message to IDE /// /// Boolean value if we already sent message to IDE internal void AggregateIsMessageSent(bool isMessageSent) @@ -170,10 +182,10 @@ internal void AggregateIsMessageSent(bool isMessageSent) /// internal ICollection GetSourcesWithStatus(DiscoveryStatus status) { - if (SourceStatusMap == null || SourceStatusMap.IsEmpty) return new List(); + if (SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.IsEmpty) return new List(); - return SourceStatusMap.Where(source => source.Value == status) - .Select(source => source.Key).ToList(); + return SourcesWithDiscoveryStatus.Where(source => source.Value == status) + .Select(source => source.Key).ToList(); } #endregion diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 9e58ca58a4..accfbfa4e2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -82,7 +82,7 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete // If we come here it means that some source was already fully discovered so we can mark it if (!discoveryDataAggregator.IsAborted) { - AggregateComingSources(discoveryDataAggregator, lastChunk); + AggregateComingSourcesAsFullyDiscovered(lastChunk, discoveryCompleteEventArgs); } } @@ -100,8 +100,8 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete var partiallyDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered) as IReadOnlyCollection; var notDiscovered = discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered) as IReadOnlyCollection; - // If parallel discovery completed because of abortion - // we need to set isAborted to true and totalTests = -1 + // As we immediatelly return results to IDE in case of aborting + // we need to set isAborted = true and totalTests = -1 if (this.parallelProxyDiscoveryManager.IsAbortRequested) { discoveryDataAggregator.Aggregate(-1, true); @@ -127,7 +127,7 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete testDiscoveryCompletePayload.Metrics = aggregatedDiscoveryDataMetrics; // Sending discovery complete message to IDE - this.SendMessage(discoveryDataAggregator, testDiscoveryCompletePayload); + this.SendMessage(testDiscoveryCompletePayload); var finalDiscoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(this.discoveryDataAggregator.TotalTests, this.discoveryDataAggregator.IsAborted, @@ -192,10 +192,10 @@ private void ConvertToRawMessageAndSend(string messageType, object payload) /// /// Discovery aggregator to know if we already sent this message /// Discovery complete payload to send - private void SendMessage(ParallelDiscoveryDataAggregator discoveryDataAggregator, DiscoveryCompletePayload testDiscoveryCompletePayload) + private void SendMessage(DiscoveryCompletePayload testDiscoveryCompletePayload) { // In case of abort scenario, we need to send raw message to IDE only once after abortion. - // All other testhost which will finish after shouldn't send raw message + // All other testhosts which will finish after shouldn't send raw message if (!discoveryDataAggregator.IsMessageSent) { lock (sendMessageLock) @@ -210,30 +210,29 @@ private void SendMessage(ParallelDiscoveryDataAggregator discoveryDataAggregator } } - /// - /// Getting the source name from the last chunk - /// - /// The last test case chunk which was discovered - /// The source of the last test case chunk - private string GetTheSourceFromTheLastChunk(IEnumerable lastChunk) - { - if (lastChunk == null || lastChunk.Count() == 0) return string.Empty; - - var chunk = lastChunk.Last(); - - return chunk.Source; - } - /// /// Aggregate source as fully discovered /// /// Aggregator to aggregate results /// Last chunk of discovered test cases - private void AggregateComingSources(ParallelDiscoveryDataAggregator discoveryDataAggregator, IEnumerable lastChunk) + private void AggregateComingSourcesAsFullyDiscovered(IEnumerable lastChunk, DiscoveryCompleteEventArgs discoveryCompleteEventArgs) { - string source = GetTheSourceFromTheLastChunk(lastChunk); + if (lastChunk == null) return; + + IEnumerable lastChunkSources; + + // Sometimes we get lastChunk as empty list (when number of tests in project dividable by 10) + // Then we will take sources from discoveryCompleteEventArgs coming from testhost + if (lastChunk.Count() == 0) + { + lastChunkSources = discoveryCompleteEventArgs.FullyDiscoveredSources; + } + else + { + lastChunkSources = lastChunk.Select(testcase => testcase.Source); + } - discoveryDataAggregator.AggregateTheSourceAsFullyDiscovered(source); + discoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index 1021243011..c755746895 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -281,7 +281,7 @@ private void MarkAllSourcesAsNotDiscovered(IEnumerable sources) { foreach (string source in sources) { - this.currentDiscoveryDataAggregator.SourceStatusMap[source] = DiscoveryStatus.NotDiscovered; + this.currentDiscoveryDataAggregator.SourcesWithDiscoveryStatus[source] = DiscoveryStatus.NotDiscovered; } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs index 3e81899d49..06b8bc8e0f 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs @@ -198,6 +198,12 @@ public void Abort() /// public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { + // Do nothing if the proxy is not initialized yet. + if (this.proxyOperationManager == null) + { + return; + } + if (this.baseTestDiscoveryEventsHandler == null) { this.baseTestDiscoveryEventsHandler = eventHandler; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 205816f128..6295edd1df 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -37,7 +37,7 @@ public class DiscoveryManager : IDiscoveryManager private DiscoveryCriteria discoveryCriteria; private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); private string previousSource = null; - private ConcurrentDictionary DiscoveredSourcesWithStatus { get; set; } = new ConcurrentDictionary(); + private ConcurrentDictionary SourcesWithDiscoveryStatus { get; set; } = new ConcurrentDictionary(); /// /// Initializes a new instance of the class. @@ -138,9 +138,6 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve { if (lastChunk != null) { - if (!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - UpdateTestCases(lastChunk, this.discoveryCriteria.Package); /* When discovery is complete we will have case that the last discovered source is still marked as partiallyDiscovered. * So we need to mark it as fullyDiscovered.*/ @@ -344,8 +341,8 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas { string currentSource = testCase.Source; - // If it is first list of testCases which was discovered, we mark sources as partiallyDiscovered - // Or if current source is the same as previous we mark them as partiallyDiscovered again for consistency + // If it is the first list of testCases which was discovered, we mark sources as partiallyDiscovered. + // Or if current source is the same as previous we again mark them as partiallyDiscovered for consistency if (previousSource is null || previousSource == currentSource) { MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); @@ -368,10 +365,14 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Last chunk of testCases which were discovered private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) { - if (lastChunk == null || lastChunk.Count == 0) return; + if (lastChunk == null) return; var lastChunkSources = lastChunk.Select(testcase => testcase.Source); + // When all testcases in project is dividable by 10 then lastChunk is coming as empty + // So we need to take the lastSource and mark it as FullyDiscovered + if (lastChunk.Count == 0) lastChunkSources = new List() { previousSource }; + MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } @@ -383,7 +384,15 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) private void MarkSourceWithStatus(string source, DiscoveryStatus status) { if (source == null) return; - DiscoveredSourcesWithStatus[source] = status; + + if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + { + EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); + } + else + { + SourcesWithDiscoveryStatus[source] = status; + } } /// @@ -397,7 +406,22 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus foreach (var source in sources) { - DiscoveredSourcesWithStatus[source] = status; + if (source == null) continue; + + // It is the first time when we fill our map with sources + if (status == DiscoveryStatus.NotDiscovered) SourcesWithDiscoveryStatus[source] = status; + + else + { + if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + { + EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); + } + else + { + SourcesWithDiscoveryStatus[source] = status; + } + } } } @@ -408,16 +432,14 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus /// private IReadOnlyCollection GetFilteredSources(DiscoveryStatus discoveryStatus) { - var discoveredSources = DiscoveredSourcesWithStatus; - - // If by some accident discoveredSources map is empty we will return empty list - if (discoveredSources == null || discoveredSources.Count == 0) + // If by some accident SourcesWithDiscoveryStatus map is empty we will return empty list + if (SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.Count == 0) { return new List(); } - return discoveredSources.Where(source => source.Value == discoveryStatus) - .Select(source => source.Key).ToList(); + return SourcesWithDiscoveryStatus.Where(source => source.Value == discoveryStatus) + .Select(source => source.Key).ToList(); } } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs index caaf2bfdef..3bf6f9f6ae 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs @@ -62,17 +62,17 @@ public DiscoveryCompleteEventArgs(long totalTests, bool isAborted) public IDictionary Metrics { get; set; } /// - /// Gets list of sources which were fully discovered + /// Gets the list of sources which were fully discovered. /// public IReadOnlyCollection FullyDiscoveredSources { get; } = new List(); /// - /// Gets list of sources which were partially discovered (started discover tests, but then discovery aborted) + /// Gets the list of sources which were partially discovered (started discover tests, but then discovery aborted). /// public IReadOnlyCollection PartiallyDiscoveredSources { get; } = new List(); /// - /// Gets list of sources which were not discovered at all + /// Gets the list of sources which were not discovered at all. /// public IReadOnlyCollection NotDiscoveredSources { get; } = new List(); } diff --git a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs index a50933508b..f621885063 100644 --- a/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs +++ b/src/Microsoft.TestPlatform.VsTestConsole.TranslationLayer/VsTestConsoleRequestSender.cs @@ -5,7 +5,6 @@ namespace Microsoft.TestPlatform.VsTestConsole.TranslationLayer { using System; using System.Collections.Generic; - using System.Diagnostics; using System.Linq; using System.Net; using System.Threading; @@ -1024,9 +1023,6 @@ private void SendMessageAndListenAndReportTestCases( this.dataSerializer .DeserializePayload(message); - if(!Debugger.IsAttached) Debugger.Launch(); - else Debugger.Break(); - var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( discoveryCompletePayload.TotalTests, discoveryCompletePayload.IsAborted, diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index 1ca2d84927..42a3231d30 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -525,7 +525,7 @@ public void CancelTestRun() /// public void CancelDiscovery() { - EqtTrace.Info("TestRequestManager.CancelTestDiscovery: Sending cancel request."); + EqtTrace.Info("TestRequestManager.CancelDiscovery: Sending cancel request."); this.currentDiscoveryRequest?.Abort(); } From 0fb8aff143a01bae79980e13c97dd5f77722b75d Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Mon, 29 Nov 2021 18:27:21 +0100 Subject: [PATCH 10/31] writing first part of tests --- .../ParallelDiscoveryDataAggregator.cs | 8 ++++ .../Discovery/DiscoveryManager.cs | 4 +- .../ParallelDiscoveryDataAggregatorTests.cs | 38 +++++++++++++++ .../Discovery/DiscoveryManagerTests.cs | 48 ++++++++++++------- 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index 770c666bcc..2d2d9c9987 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -154,6 +154,8 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources foreach (var source in sources) { + if (status == DiscoveryStatus.NotDiscovered) SourcesWithDiscoveryStatus[source] = status; + if (!SourcesWithDiscoveryStatus.ContainsKey(source)) { EqtTrace.Warning($"ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus : " + @@ -162,6 +164,12 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources else { SourcesWithDiscoveryStatus[source] = status; + + if (EqtTrace.IsInfoEnabled) + { + EqtTrace.Info($"ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus : " + + $"{source} is marked with {status} status"); + } } } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 6295edd1df..addef943c6 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -392,6 +392,7 @@ private void MarkSourceWithStatus(string source, DiscoveryStatus status) else { SourcesWithDiscoveryStatus[source] = status; + EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : Marking {source} with {status} status"); } } @@ -415,11 +416,12 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus { if (!SourcesWithDiscoveryStatus.ContainsKey(source)) { - EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); + EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); } else { SourcesWithDiscoveryStatus[source] = status; + EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : Marking {source} with {status} status"); } } } diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs index c8d1e1ec8a..014ae33c99 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs @@ -8,6 +8,7 @@ namespace TestPlatform.CrossPlatEngine.UnitTests.Client.Parallel using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; + using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -224,5 +225,42 @@ public void GetDiscoveryDataMetricsShouldNotAddNumberOfAdapterDiscoveredIfMetric Assert.IsFalse(runMetrics.TryGetValue(TelemetryDataConstants.NumberOfAdapterDiscoveredDuringDiscovery, out var value)); } + + [TestMethod] + public void AggregateShouldAggregateMessageSentCorrectly() + { + var aggregator = new ParallelDiscoveryDataAggregator(); + + aggregator.AggregateIsMessageSent(isMessageSent: false); + Assert.IsFalse(aggregator.IsMessageSent, "Aborted must be false"); + + aggregator.AggregateIsMessageSent(isMessageSent: true); + Assert.IsTrue(aggregator.IsMessageSent, "Aborted must be true"); + + aggregator.AggregateIsMessageSent(isMessageSent: false); + Assert.IsTrue(aggregator.IsMessageSent, "Aborted must be true"); + } + + [TestMethod] + public void AggregateShouldAggregateSourcesCorrectly() + { + // Arrange + var aggregator = new ParallelDiscoveryDataAggregator(); + var sources = new List() { "sample.dll" }; + + // Act + aggregator.AggregateTheSourcesWithDiscoveryStatus(sources, DiscoveryStatus.NotDiscovered); + var sourcesWithNotDiscoveredStatus = aggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered); + + // Assert + Assert.AreEqual(1, sourcesWithNotDiscoveredStatus.Count); + + // Act + aggregator.AggregateTheSourcesWithDiscoveryStatus(sources, DiscoveryStatus.FullyDiscovered); + var sourcesWithFullyDiscoveryStatus = aggregator.GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered); + + // Assert + Assert.AreEqual(1, sourcesWithFullyDiscoveryStatus.Count); + } } } diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs index d7d956b4be..0f3ed56821 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs @@ -82,10 +82,7 @@ public void DiscoverTestsShouldLogIfTheSourceDoesNotExist() var errorMessage = string.Format(CultureInfo.CurrentCulture, "Could not find file {0}.", Path.Combine(Directory.GetCurrentDirectory(), "imaginary.dll")); mockLogger.Verify( l => - l.HandleLogMessage( - Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel.Warning, - errorMessage), - Times.Once); + l.HandleLogMessage(TestMessageLevel.Warning,errorMessage),Times.Once); } [TestMethod] @@ -105,10 +102,7 @@ public void DiscoverTestsShouldLogIfTheSourceDoesNotExistIfItHasAPackage() var errorMessage = string.Format(CultureInfo.CurrentCulture, "Could not find file {0}.", Path.Combine(fakeDirectory, "imaginary.exe")); mockLogger.Verify( l => - l.HandleLogMessage( - Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel.Warning, - errorMessage), - Times.Once); + l.HandleLogMessage(TestMessageLevel.Warning,errorMessage),Times.Once); } [TestMethod] @@ -124,10 +118,7 @@ public void DiscoverTestsShouldLogIfThereAreNoValidSources() var errorMessage = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.NoValidSourceFoundForDiscovery, sourcesString); mockLogger.Verify( l => - l.HandleLogMessage( - Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel.Warning, - errorMessage), - Times.Once); + l.HandleLogMessage(TestMessageLevel.Warning,errorMessage),Times.Once); } [TestMethod] @@ -151,10 +142,7 @@ public void DiscoverTestsShouldLogIfTheSameSourceIsSpecifiedTwice() var errorMessage = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.DuplicateSource, sources[0]); mockLogger.Verify( l => - l.HandleLogMessage( - Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging.TestMessageLevel.Warning, - errorMessage), - Times.Once); + l.HandleLogMessage(TestMessageLevel.Warning,errorMessage),Times.Once); } [TestMethod] @@ -266,6 +254,34 @@ public void DiscoveryInitializeShouldVerifyWarningMessageIfAdapterFailedToLoad() mockLogger.Verify(rd => rd.HandleLogMessage(TestMessageLevel.Warning, "verify that the HandleLogMessage method getting invoked at least once"), Times.Once); } + [TestMethod] + public void DiscoveryTestsShouldSendAbortValuesCorrectlyIfAbortionHappened() + { + // Arrange + var sources = new List { typeof(DiscoveryManagerTests).GetTypeInfo().Assembly.Location }; + + var criteria = new DiscoveryCriteria(sources, 100, null); + var mockHandler = new Mock(); + + DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; + + mockHandler.Setup(ml => ml.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) + .Callback( + (DiscoveryCompleteEventArgs complete, + IEnumerable tests) => + { + receivedDiscoveryCompleteEventArgs = complete; + }); + + // Act + this.discoveryManager.DiscoverTests(criteria, mockHandler.Object); + this.discoveryManager.Abort(mockHandler.Object); + + // Assert + Assert.AreEqual(true, receivedDiscoveryCompleteEventArgs.IsAborted); + Assert.AreEqual(-1, receivedDiscoveryCompleteEventArgs.TotalCount); + } + #endregion } } From a220af595f72407eefec116f4fc7cb808d6078d9 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Wed, 1 Dec 2021 17:08:35 +0100 Subject: [PATCH 11/31] more tests --- .../ParallelDiscoveryEventsHandlerTests.cs | 21 +++++ .../ParallelProxyDiscoveryManagerTests.cs | 53 ++++++++---- .../VsTestConsoleRequestSenderTests.cs | 86 +++++++++++++++++++ 3 files changed, 141 insertions(+), 19 deletions(-) diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs index 4ba1536d27..14ae4b6225 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs @@ -148,6 +148,27 @@ public void HandleDiscoveryCompleteShouldCallTestDiscoveryCompleteOnActualHandle this.mockTestDiscoveryEventsHandler.Verify(mt => mt.HandleDiscoveryComplete(It.IsAny(), null), Times.Once); } + [TestMethod] + public void HandleDiscoveryCompleteShouldCallConvertToRawMessageAndSendOnceIfDiscoveryIsComplete() + { + string payload = "DiscoveryComplete"; + int totalTests = 10; + bool aborted = false; + + this.mockParallelProxyDiscoveryManager.Setup(mp => mp.HandlePartialDiscoveryComplete( + this.mockProxyDiscoveryManager.Object, totalTests, null, aborted)).Returns(true); + + this.mockDataSerializer.Setup(mds => mds.SerializeMessage(MessageType.DiscoveryComplete)).Returns(payload); + + // Act + var discoveryCompleteEventsArgs = new DiscoveryCompleteEventArgs(totalTests, aborted, It.IsAny>(), It.IsAny>(), It.IsAny>()); + this.parallelDiscoveryEventsHandler.HandleDiscoveryComplete(discoveryCompleteEventsArgs, null); + + // Verify + this.mockTestDiscoveryEventsHandler.Verify(mt => mt.HandleRawMessage(It.IsAny()), Times.Once); + this.mockTestDiscoveryEventsHandler.Verify(mt => mt.HandleDiscoveryComplete(It.IsAny(), null), Times.Once); + } + [TestMethod] public void HandleDiscoveryTestsShouldJustPassOnTheEventToDiscoveryEventsHandler() { diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs index d9f85b420b..0dec321e79 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelProxyDiscoveryManagerTests.cs @@ -3,11 +3,6 @@ namespace TestPlatform.CrossPlatEngine.UnitTests.Client { - using System; - using System.Collections.Generic; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces; using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel; @@ -19,8 +14,11 @@ namespace TestPlatform.CrossPlatEngine.UnitTests.Client using Microsoft.VisualStudio.TestPlatform.ObjectModel.Host; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; - using Moq; + using System; + using System.Collections.Generic; + using System.Threading; + using System.Threading.Tasks; [TestClass] public class ParallelProxyDiscoveryManagerTests @@ -101,12 +99,32 @@ public void DiscoverTestsShouldProcessAllSources() AssertMissingAndDuplicateSources(processedSources); } - /// - /// Create ParallelProxyDiscoveryManager with parallel level 1 and two source, - /// Abort in any source should not stop discovery for other sources. - /// [TestMethod] - public void DiscoveryTestsShouldProcessAllSourcesOnDiscoveryAbortsForAnySource() + public void HandlePartialDiscoveryCompleteShouldReturnTrueIfDiscoveryWasAbortedWithEventHandler() + { + var parallelDiscoveryManager = new ParallelProxyDiscoveryManager(this.mockRequestData.Object, this.proxyManagerFunc, 1, false); + var proxyDiscovermanager = new ProxyDiscoveryManager(this.mockRequestData.Object, new Mock().Object, new Mock().Object); + + parallelDiscoveryManager.Abort(this.mockHandler.Object); + bool isPartialDiscoveryComplete = parallelDiscoveryManager.HandlePartialDiscoveryComplete(proxyDiscovermanager, 20, new List(), isAborted: false); + + Assert.IsTrue(isPartialDiscoveryComplete); + } + + [TestMethod] + public void HandlePartialDiscoveryCompleteShouldReturnTrueIfDiscoveryWasAborted() + { + var parallelDiscoveryManager = new ParallelProxyDiscoveryManager(this.mockRequestData.Object, this.proxyManagerFunc, 1, false); + var proxyDiscovermanager = new ProxyDiscoveryManager(this.mockRequestData.Object, new Mock().Object, new Mock().Object); + + parallelDiscoveryManager.Abort(); + bool isPartialDiscoveryComplete = parallelDiscoveryManager.HandlePartialDiscoveryComplete(proxyDiscovermanager, 20, new List(), isAborted: false); + + Assert.IsTrue(isPartialDiscoveryComplete); + } + + [TestMethod] + public void DiscoveryTestsShouldStopDiscoveryIfAbortionWasRequested() { // Since the hosts are aborted, total aggregated tests sent across will be -1 var discoveryManagerMock = new Mock(); @@ -116,18 +134,15 @@ public void DiscoveryTestsShouldProcessAllSourcesOnDiscoveryAbortsForAnySource() Task.Run(() => { parallelDiscoveryManager.DiscoverTests(this.testDiscoveryCriteria, this.mockHandler.Object); + parallelDiscoveryManager.Abort(); }); - Assert.IsTrue(this.discoveryCompleted.Wait(ParallelProxyDiscoveryManagerTests.taskTimeout), "Test discovery not completed."); - Assert.AreEqual(2, processedSources.Count, "All Sources must be processed."); + Assert.IsTrue(this.discoveryCompleted.Wait(taskTimeout), "Test discovery not completed."); + Assert.AreEqual(1, processedSources.Count, "One source should be processed."); } - /// - /// Create ParallelProxyDiscoveryManager with parallel level 1 and two sources, - /// Overall discovery should stop, if aborting was requested - /// [TestMethod] - public void DiscoveryTestsShouldStopDiscoveryIfAbortionWasRequested() + public void DiscoveryTestsShouldStopDiscoveryIfAbortionWithEventHandlerWasRequested() { // Since the hosts are aborted, total aggregated tests sent across will be -1 var discoveryManagerMock = new Mock(); @@ -137,7 +152,7 @@ public void DiscoveryTestsShouldStopDiscoveryIfAbortionWasRequested() Task.Run(() => { parallelDiscoveryManager.DiscoverTests(this.testDiscoveryCriteria, this.mockHandler.Object); - parallelDiscoveryManager.Abort(); + parallelDiscoveryManager.Abort(mockHandler.Object); }); Assert.IsTrue(this.discoveryCompleted.Wait(taskTimeout), "Test discovery not completed."); diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs index 202b60a0c6..e2ea55a0cc 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs @@ -429,6 +429,92 @@ public async Task DiscoverTestsAsyncShouldCompleteWithSingleTest() mockHandler.Verify(mh => mh.HandleLogMessage(It.IsAny(), It.IsAny()), Times.Never, "TestMessage event must not be called"); } + [TestMethod] + public void DiscoverTestsShouldCompleteWithSingleFullyDiscoveredSource() + { + this.InitializeCommunication(); + + var mockHandler = new Mock(); + + List sources = new List() { "1.dll" }; + + var testCase = new TestCase("hello", new Uri("world://how"), source: sources[0]); + var testsFound = new Message() + { + MessageType = MessageType.TestCasesFound, + Payload = JToken.FromObject(new List() { testCase }) + }; + + var payload = new DiscoveryCompletePayload() { TotalTests = 1, LastDiscoveredTests = null, IsAborted = false, FullyDiscoveredSources = sources }; + var discoveryComplete = new Message() + { + MessageType = MessageType.DiscoveryComplete, + Payload = JToken.FromObject(payload) + }; + + DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; + + this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(testsFound)); + mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())).Callback( + () => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); + + mockHandler.Setup(mh => mh.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) + .Callback((DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable tests) => + { receivedDiscoveryCompleteEventArgs = discoveryCompleteEventArgs;}); + + this.requestSender.DiscoverTests(sources, null, new TestPlatformOptions(), null, mockHandler.Object); + + mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); + Assert.IsNotNull(receivedDiscoveryCompleteEventArgs.FullyDiscoveredSources); + Assert.AreEqual(1, receivedDiscoveryCompleteEventArgs.FullyDiscoveredSources.Count); + } + + [TestMethod] + public void DiscoverTestsShouldCompleteWithCorrectAbortedValuesIfAbortingWasRequsted() + { + // Arrange + this.InitializeCommunication(); + + var mockHandler = new Mock(); + + List sources = new List() { "1.dll" }; + + var testCase = new TestCase("hello", new Uri("world://how"), source: sources[0]); + var testsFound = new Message() + { + MessageType = MessageType.TestCasesFound, + Payload = JToken.FromObject(new List() { testCase }) + }; + + var payload = new DiscoveryCompletePayload() { TotalTests = -1, LastDiscoveredTests = null, IsAborted = true, FullyDiscoveredSources = sources }; + var discoveryComplete = new Message() + { + MessageType = MessageType.DiscoveryComplete, + Payload = JToken.FromObject(payload) + }; + + DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; + + this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(testsFound)); + mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())).Callback( + () => this.mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); + + mockHandler.Setup(mh => mh.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) + .Callback((DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable tests) => + { receivedDiscoveryCompleteEventArgs = discoveryCompleteEventArgs; }); + + // Act + this.requestSender.DiscoverTests(sources, null, new TestPlatformOptions(), null, mockHandler.Object); + this.requestSender.CancelDiscovery(); + + // Assert + mockHandler.Verify(mh => mh.HandleDiscoveryComplete(It.IsAny(), null), Times.Once, "Discovery Complete must be called"); + Assert.IsNotNull(receivedDiscoveryCompleteEventArgs.FullyDiscoveredSources); + Assert.AreEqual(1, receivedDiscoveryCompleteEventArgs.FullyDiscoveredSources.Count); + Assert.AreEqual(-1, receivedDiscoveryCompleteEventArgs.TotalCount); + Assert.AreEqual(true, receivedDiscoveryCompleteEventArgs.IsAborted); + } + [TestMethod] public void DiscoverTestsShouldReportBackTestsWithTraitsInTestsFoundMessage() { From adfdabb8ec41c4738a51217ddf821f7c3c02516d Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Thu, 2 Dec 2021 15:31:24 +0100 Subject: [PATCH 12/31] fixing public api --- .../PublicAPI/net451/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt index e69de29bb2..0f1022956e 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index e69de29bb2..0f1022956e 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..0f1022956e 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file From c094306ba77d0d5fc3ce871c598821a443d1fb04 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Thu, 2 Dec 2021 16:03:36 +0100 Subject: [PATCH 13/31] more public api --- .../PublicAPI/net451/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 2 ++ 8 files changed, 34 insertions(+) diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt index e69de29bb2..408b735f89 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void +Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..408b735f89 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void +Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt index e69de29bb2..1c90267bfa 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index e69de29bb2..1c90267bfa 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..1c90267bfa 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt index e69de29bb2..8a84288ee8 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index e69de29bb2..8a84288ee8 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index e69de29bb2..8a84288ee8 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file From 31ebaa076f9a16f76a117b03491885870b3c5ce6 Mon Sep 17 00:00:00 2001 From: Sanan Yuzbashiyev Date: Fri, 3 Dec 2021 13:12:44 +0100 Subject: [PATCH 14/31] changing public api files --- .../PublicAPI/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 2 -- .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 2 -- .../PublicAPI/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/PublicAPI.Unshipped.txt | 8 ++++++++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 8 -------- .../PublicAPI/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/net451/PublicAPI.Unshipped.txt | 2 -- .../PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt | 2 -- .../PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt | 2 -- 15 files changed, 20 insertions(+), 58 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..408b735f89 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void +Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt index 408b735f89..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -1,2 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void -Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 408b735f89..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void -Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..0f1022956e 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt index 0f1022956e..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index 0f1022956e..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 0f1022956e..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..1c90267bfa 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,8 @@ +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt index 1c90267bfa..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index 1c90267bfa..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 1c90267bfa..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,8 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Unshipped.txt index e69de29bb2..8a84288ee8 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1,2 @@ +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void +Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt index 8a84288ee8..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/net451/PublicAPI.Unshipped.txt @@ -1,2 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt index 8a84288ee8..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard1.3/PublicAPI.Unshipped.txt @@ -1,2 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 8a84288ee8..e69de29bb2 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +0,0 @@ -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery.DiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void \ No newline at end of file From 50c713e428d95f92ec9a2f4d7b214b993068b740 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 10 Feb 2022 15:48:13 +0100 Subject: [PATCH 15/31] Update src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs --- .../Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs index 80b3005107..3417f8675b 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IProxyDiscoveryManager.cs @@ -34,7 +34,6 @@ public interface IProxyDiscoveryManager /// EventHandler for handling discovery events from Engine void Abort(ITestDiscoveryEventsHandler2 eventHandler); - /// /// Closes the current test operation. /// Send a EndSession message to close the test host and channel gracefully. From 29377a34fd18133cb079eaab88ea5169e9617cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 10 Feb 2022 16:24:54 +0100 Subject: [PATCH 16/31] Apply suggestions from code review --- .../RequestHelper/ITestRequestManager.cs | 2 +- .../Engine/TesthostProtocol/IDiscoveryManager.cs | 2 +- .../Interfaces/ITestRequestSender.cs | 2 +- .../Messages/DiscoveryCompletePayload.cs | 6 +++--- .../Parallel/ParallelDiscoveryDataAggregator.cs | 12 ++++++------ .../Parallel/ParallelDiscoveryEventsHandler.cs | 2 +- .../Client/Interfaces/IDiscoveryRequest.cs | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index 13fa6d7f35..7e223f415f 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -104,7 +104,7 @@ void StartTestSession( void CancelDiscovery(); /// - /// Cancels the current discovery request with discovery complete event handler + /// Cancels the current discovery request with discovery complete event handler. /// void CancelDiscoveryWithEventHandler(); diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs index ffbd285fd8..b2bc78bf15 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/TesthostProtocol/IDiscoveryManager.cs @@ -31,7 +31,7 @@ public interface IDiscoveryManager void Abort(); /// - /// Aborts the test discovery with eventHandler + /// Aborts the test discovery with eventHandler. /// /// EventHandler for handling discovery events from Engine void Abort(ITestDiscoveryEventsHandler2 eventHandler); diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs index f02e81a7a8..e532598f67 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Interfaces/ITestRequestSender.cs @@ -88,7 +88,7 @@ public interface ITestRequestSender : IDisposable void SendTestRunAbort(); /// - /// Send the request to abort the discovery + /// Sends the request to abort the discovery. /// void SendDiscoveryAbort(); diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs index 9d1026698a..864b78f2ff 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs @@ -33,17 +33,17 @@ public class DiscoveryCompletePayload public IDictionary Metrics { get; set; } /// - /// Gets or sets list of sources which were fully discovered + /// Gets or sets list of sources which were fully discovered. /// public IReadOnlyCollection FullyDiscoveredSources { get; set; } = new List(); /// - /// Gets or sets list of sources which were partially discovered (started discover tests, but then discovery aborted) + /// Gets or sets list of sources which were partially discovered (started discover tests, but then discovery aborted). /// public IReadOnlyCollection PartiallyDiscoveredSources { get; set; } = new List(); /// - /// Gets or sets list of sources which were not discovered at all + /// Gets or sets list of sources which were not discovered at all. /// public IReadOnlyCollection NotDiscoveredSources { get; set; } = new List(); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index bb6ac5f2d7..14dee4f340 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -160,8 +160,8 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources if (!SourcesWithDiscoveryStatus.ContainsKey(source)) { - EqtTrace.Warning($"ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus : " + - $"{source} is not present in SourcesWithDiscoveryStatus dictionary"); + EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + + $"{source} is not present in SourcesWithDiscoveryStatus dictionary."); } else { @@ -169,15 +169,15 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources if (EqtTrace.IsInfoEnabled) { - EqtTrace.Info($"ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus : " + - $"{source} is marked with {status} status"); + EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + + $"{source} is marked with {status} status."); } } } } /// - /// Aggregate the value indicating if we already sent message to IDE + /// Aggregates the value indicating if we already sent message to IDE. /// /// Boolean value if we already sent message to IDE internal void AggregateIsMessageSent(bool isMessageSent) @@ -186,7 +186,7 @@ internal void AggregateIsMessageSent(bool isMessageSent) } /// - /// Returning sources with particular discovery status + /// Returns sources with particular discovery status. /// /// Status to filter /// diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 9595271a7c..cf1d369805 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -101,7 +101,7 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete var partiallyDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered) as IReadOnlyCollection; var notDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered) as IReadOnlyCollection; - // As we immediatelly return results to IDE in case of aborting + // As we immediately return results to IDE in case of aborting // we need to set isAborted = true and totalTests = -1 if (_parallelProxyDiscoveryManager.IsAbortRequested) { diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs index 87a2a3456d..952a170c98 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs @@ -52,7 +52,7 @@ DiscoveryCriteria DiscoveryCriteria void Abort(); /// - /// Aborts the discovery request with event handler + /// Aborts the discovery request with event handler. /// void AbortWithEventHandler(); } From f1c872b917c277d6856fa156f9ccb602824a3c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 10 Feb 2022 17:34:32 +0100 Subject: [PATCH 17/31] Fix incorrect merges + address analyzer warnings --- .../Discovery/DiscoveryRequest.cs | 16 +++------------- .../Engine/ClientProtocol/DiscoveryStatus.cs | 14 ++++++++++++++ .../IParallelProxyDiscoveryManager.cs | 10 ---------- .../PublicAPI/PublicAPI.Unshipped.txt | 8 ++++---- .../Parallel/ParallelDiscoveryDataAggregator.cs | 3 +-- .../Parallel/ParallelDiscoveryEventsHandler.cs | 13 ++++++------- .../Parallel/ParallelProxyDiscoveryManager.cs | 5 ++--- .../Discovery/DiscovererEnumerator.cs | 1 - .../Discovery/DiscoveryManager.cs | 14 +++++++------- .../TranslationLayerTests/DiscoverTests.cs | 2 +- .../ParallelDiscoveryDataAggregatorTests.cs | 6 ++---- .../Discovery/DiscoveryManagerTests.cs | 7 +------ .../Execution/TestRunCacheTests.cs | 2 +- .../RunSettings/RunSettingsTests.cs | 2 -- 14 files changed, 42 insertions(+), 61 deletions(-) create mode 100644 src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index 1299cddc6e..7f3e2aaa6c 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -167,10 +167,7 @@ bool IRequest.WaitForCompletion(int timeout) /// public void AbortWithEventHandler() { - if (EqtTrace.IsVerboseEnabled) - { - EqtTrace.Verbose("DiscoveryRequest.AbortWithEventHandler: Aborting."); - } + EqtTrace.Verbose("DiscoveryRequest.AbortWithEventHandler: Aborting."); lock (_syncObject) { @@ -185,19 +182,12 @@ public void AbortWithEventHandler() } else { - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: No operation to abort."); - } - + EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: No operation to abort."); return; } } - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: Aborted."); - } + EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: Aborted."); } /// diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs new file mode 100644 index 0000000000..e7a67a49c2 --- /dev/null +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs @@ -0,0 +1,14 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; + +/// +/// Enums for indicating discovery status of source +/// +public enum DiscoveryStatus +{ + FullyDiscovered, // Indicates that source was fully discovered + PartiallyDiscovered, // Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it + NotDiscovered // Indicates the sources which were not touched during discovery +} diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs index 665b9e8a1b..ca7c4f7f46 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs @@ -29,14 +29,4 @@ bool HandlePartialDiscoveryComplete( long totalTests, IEnumerable lastChunk, bool isAborted); - - /// - /// Enums for indicating discovery status of source - /// - public enum DiscoveryStatus - { - FullyDiscovered, // Indicates that source was fully discovered - PartiallyDiscovered, // Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it - NotDiscovered // Indicates the sources which were not touched during discovery - } } diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt index 5af2ae75a5..a16b0f825c 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt @@ -2,7 +2,7 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryMa Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index 14dee4f340..e6665f3799 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -6,14 +6,13 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; using Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using static Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager; - /// /// ParallelDiscoveryDataAggregator aggregates discovery data from parallel discovery managers /// diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index cf1d369805..4b53e06663 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -16,7 +16,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; using ObjectModel.Logging; using CommonResources = Common.Resources.Resources; -using static Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager; /// /// ParallelDiscoveryEventsHandler for handling the discovery events in case of parallel discovery @@ -35,7 +34,7 @@ internal class ParallelDiscoveryEventsHandler : ITestDiscoveryEventsHandler2 private readonly IRequestData _requestData; - private readonly object sendMessageLock = new(); + private readonly object _sendMessageLock = new(); public ParallelDiscoveryEventsHandler(IRequestData requestData, IProxyDiscoveryManager proxyDiscoveryManager, @@ -90,10 +89,10 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete // Do not send TestDiscoveryComplete to actual test discovery handler // We need to see if there are still sources left - let the parallel manager decide var parallelDiscoveryComplete = _parallelProxyDiscoveryManager.HandlePartialDiscoveryComplete( - _proxyDiscoveryManager, - totalTests, - null, // lastChunk should be null as we already sent this data above - isAborted); + _proxyDiscoveryManager, + totalTests, + null, // lastChunk should be null as we already sent this data above + isAborted); if (parallelDiscoveryComplete) { @@ -199,7 +198,7 @@ private void SendMessage(DiscoveryCompletePayload testDiscoveryCompletePayload) // All other testhosts which will finish after shouldn't send raw message if (!_discoveryDataAggregator.IsMessageSent) { - lock (sendMessageLock) + lock (_sendMessageLock) { if (!_discoveryDataAggregator.IsMessageSent) { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index 6f9b73171c..2e9140d29e 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -15,7 +15,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using ObjectModel.Engine; using ObjectModel.Logging; -using static Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager; /// /// ParallelProxyDiscoveryManager that manages parallel discovery @@ -50,7 +49,7 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager private readonly object _discoveryStatusLockObject = new(); - private readonly object enumeratorLockObject = new(); + private readonly object _enumeratorLockObject = new(); #endregion @@ -279,7 +278,7 @@ private void MarkAllSourcesAsNotDiscovered(IEnumerable sources) { if (sources == null || sources.Count() == 0) return; - lock (enumeratorLockObject) + lock (_enumeratorLockObject) { foreach (string source in sources) { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs index d9ea5c18bb..f631481ef6 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscovererEnumerator.cs @@ -5,7 +5,6 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery; using System; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 05a9fd5685..534dabdf39 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -22,9 +22,9 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; using ObjectModel.Engine.TesthostProtocol; using ObjectModel.Logging; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using CrossPlatEngineResources = Resources.Resources; -using static Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager; /// /// Orchestrates discovery operations for the engine communicating with the test host process. @@ -37,7 +37,7 @@ public class DiscoveryManager : IDiscoveryManager private ITestDiscoveryEventsHandler2 _testDiscoveryEventsHandler; private DiscoveryCriteria _discoveryCriteria; private readonly CancellationTokenSource _cancellationTokenSource = new(); - private string previousSource = null; + private string _previousSource = null; private ConcurrentDictionary SourcesWithDiscoveryStatus { get; set; } = new ConcurrentDictionary(); /// @@ -347,19 +347,19 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas // If it is the first list of testCases which was discovered, we mark sources as partiallyDiscovered. // Or if current source is the same as previous we again mark them as partiallyDiscovered for consistency - if (previousSource is null || previousSource == currentSource) + if (_previousSource is null || _previousSource == currentSource) { MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); } // If source is changed, we need to mark previous source as already fullyDiscovered // and currentSource should be partiallyDiscovered - else if (currentSource != previousSource) + else if (currentSource != _previousSource) { - MarkSourceWithStatus(previousSource, DiscoveryStatus.FullyDiscovered); + MarkSourceWithStatus(_previousSource, DiscoveryStatus.FullyDiscovered); MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); } - previousSource = currentSource; + _previousSource = currentSource; } } @@ -375,7 +375,7 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) // When all testcases in project is dividable by 10 then lastChunk is coming as empty // So we need to take the lastSource and mark it as FullyDiscovered - if (lastChunk.Count == 0) lastChunkSources = new List() { previousSource }; + if (lastChunk.Count == 0) lastChunkSources = new List() { _previousSource }; MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs index 0c71ee0919..159b61b435 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs @@ -170,7 +170,7 @@ public void DisoverTestUsingEventHandler2ShouldContainAllSourcesAsFullyDiscovere [NetCoreTargetFrameworkDataSource] public void DiscoverTestsUsingSourceNavigation(RunnerInfo runnerInfo) { - AcceptanceTestBase.SetTestEnvironment(_testEnvironment, runnerInfo); + SetTestEnvironment(_testEnvironment, runnerInfo); Setup(); _vstestConsoleWrapper.DiscoverTests( diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs index d98127f64f..319ab0c3b8 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs @@ -8,10 +8,9 @@ namespace TestPlatform.CrossPlatEngine.UnitTests.Client.Parallel; using Microsoft.VisualStudio.TestPlatform.Common.Telemetry; using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using Microsoft.VisualStudio.TestTools.UnitTesting; -using static Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager; - [TestClass] public class ParallelDiscoveryDataAggregatorTests { @@ -234,8 +233,7 @@ public void GetDiscoveryDataMetricsShouldNotAddNumberOfAdapterDiscoveredIfMetric aggregator.AggregateDiscoveryDataMetrics(dict); var runMetrics = aggregator.GetAggregatedDiscoveryDataMetrics(); - - Assert.IsFalse(runMetrics.TryGetValue(TelemetryDataConstants.NumberOfAdapterDiscoveredDuringDiscovery, out var value)); + Assert.IsFalse(runMetrics.TryGetValue(TelemetryDataConstants.NumberOfAdapterDiscoveredDuringDiscovery, out _)); } [TestMethod] diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs index 8559c28cf8..31c1b6a6e8 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Discovery/DiscoveryManagerTests.cs @@ -278,12 +278,7 @@ public void DiscoveryTestsShouldSendAbortValuesCorrectlyIfAbortionHappened() DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; mockHandler.Setup(ml => ml.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) - .Callback( - (DiscoveryCompleteEventArgs complete, - IEnumerable tests) => - { - receivedDiscoveryCompleteEventArgs = complete; - }); + .Callback((DiscoveryCompleteEventArgs complete, IEnumerable tests) => receivedDiscoveryCompleteEventArgs = complete); // Act _discoveryManager.DiscoverTests(criteria, mockHandler.Object); diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/TestRunCacheTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/TestRunCacheTests.cs index 2b7936bb70..ace581e605 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/TestRunCacheTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Execution/TestRunCacheTests.cs @@ -53,7 +53,7 @@ public void OnTestStartedShouldAddMultipleInProgressTestsTillCacheHit() // var cache = new TestRunCache(int.MaxValue, cacheTimeout, tester.CacheHitOnTimerLimit); - // var tr = _GetTestResult(0); + // var tr = this.GetTestResult(0); // cache.OnTestStarted(tr.TestCase); // Assert.AreEqual(0, tester.TotalInProgressTestsReceived); diff --git a/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunSettingsTests.cs b/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunSettingsTests.cs index 0eb244a00f..b36e6abc9a 100644 --- a/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunSettingsTests.cs +++ b/test/Microsoft.TestPlatform.ObjectModel.UnitTests/RunSettings/RunSettingsTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. namespace Microsoft.TestPlatform.ObjectModel.UnitTests; - -using System.IO; using System.Xml; using System.Xml.Serialization; From 8dbbd31af9f27dd52619ff99920181b1036b844b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 10 Feb 2022 17:38:38 +0100 Subject: [PATCH 18/31] Simpliy EqtTrace calls --- .../TestRequestSender.cs | 6 +----- .../Client/Parallel/ParallelDiscoveryDataAggregator.cs | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs index fa29aeba02..48c84e90e4 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/TestRequestSender.cs @@ -305,11 +305,7 @@ public void SendDiscoveryAbort() return; } - if (EqtTrace.IsVerboseEnabled) - { - EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Sending discovery abort."); - } - + EqtTrace.Verbose("TestRequestSender.SendDiscoveryAbort: Sending discovery abort."); _channel?.Send(_dataSerializer.SerializeMessage(MessageType.CancelDiscovery)); } #endregion diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index e6665f3799..fdf3cc9268 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -166,11 +166,8 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources { SourcesWithDiscoveryStatus[source] = status; - if (EqtTrace.IsInfoEnabled) - { - EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + - $"{source} is marked with {status} status."); - } + EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + + $"{source} is marked with {status} status."); } } } From 36db6694377fd73033b948b750eb31cd17998e38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 12 Feb 2022 15:00:43 +0100 Subject: [PATCH 19/31] Remove API duplication --- .../PublicAPI/PublicAPI.Unshipped.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt index eadc47cb15..2abbcd2de4 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt @@ -1,4 +1,3 @@ Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void -Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.StopTestSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads.StopTestSessionPayload payload, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler eventsHandler, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ProtocolConfig protocolConfig) -> void From 03eab00fdcdebb789c70d3a526f7ce30f8e5a49e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 12 Feb 2022 16:47:26 +0100 Subject: [PATCH 20/31] Apply some code review comments --- .../Engine/ClientProtocol/DiscoveryStatus.cs | 17 +++++++-- .../IParallelProxyDiscoveryManager.cs | 2 +- .../PublicAPI/PublicAPI.Unshipped.txt | 1 - .../ParallelDiscoveryDataAggregator.cs | 22 ++++++------ .../ParallelDiscoveryEventsHandler.cs | 24 +++++-------- .../Parallel/ParallelProxyDiscoveryManager.cs | 2 +- .../Discovery/DiscoveryManager.cs | 36 +++++++++---------- .../Events/DiscoveryCompleteEventArgs.cs | 34 +++++++++--------- .../TranslationLayerTests/DiscoverTests.cs | 9 ++--- .../ParallelDiscoveryEventsHandlerTests.cs | 2 +- .../VsTestConsoleRequestSenderTests.cs | 10 +++--- 11 files changed, 84 insertions(+), 75 deletions(-) diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs index e7a67a49c2..f57d698742 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs @@ -8,7 +8,18 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; /// public enum DiscoveryStatus { - FullyDiscovered, // Indicates that source was fully discovered - PartiallyDiscovered, // Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it - NotDiscovered // Indicates the sources which were not touched during discovery + /// + /// Indicates that source was fully discovered. + /// + FullyDiscovered, + + /// + /// Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it. + /// + PartiallyDiscovered, + + /// + /// Indicates the sources which were not touched during discovery. + /// + NotDiscovered, } diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs index ca7c4f7f46..1dfbe89155 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/IParallelProxyDiscoveryManager.cs @@ -13,7 +13,7 @@ public interface IParallelProxyDiscoveryManager : IParallelOperationManager, IPr /// /// Indicates if user requested an abortion /// - bool IsAbortRequested { get; set; } + bool IsAbortRequested { get; } /// /// Handles Partial Discovery Complete event coming from a specific concurrent proxy discovery manager diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt index e31763064b..ec98416753 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt @@ -7,7 +7,6 @@ static Microsoft.VisualStudio.TestPlatform.Common.Telemetry.TelemetryDataConstan Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyTestSessionManager.StartSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler eventsHandler, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IRequestData requestData) -> bool Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyTestSessionManager.StopSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IRequestData requestData) -> bool Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.get -> bool -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryManager.IsAbortRequested.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index fdf3cc9268..72fc6e1535 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -51,12 +51,12 @@ public ParallelDiscoveryDataAggregator() /// /// Dictionary which stores source with corresponding discoveryStatus /// - internal ConcurrentDictionary SourcesWithDiscoveryStatus = new(); + internal ConcurrentDictionary SourcesWithDiscoveryStatus { get; } = new(); /// /// Indicates if discovery complete payload already sent back to IDE /// - internal bool IsMessageSent { get; set; } + internal bool IsMessageSent { get; private set; } #endregion @@ -159,15 +159,15 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources if (!SourcesWithDiscoveryStatus.ContainsKey(source)) { - EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + - $"{source} is not present in SourcesWithDiscoveryStatus dictionary."); + EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + + $"{source} is not present in SourcesWithDiscoveryStatus dictionary."); } else { SourcesWithDiscoveryStatus[source] = status; - EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + - $"{source} is marked with {status} status."); + EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + + $"{source} is marked with {status} status."); } } } @@ -188,10 +188,12 @@ internal void AggregateIsMessageSent(bool isMessageSent) /// internal ICollection GetSourcesWithStatus(DiscoveryStatus status) { - if (SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.IsEmpty) return new List(); - - return SourcesWithDiscoveryStatus.Where(source => source.Value == status) - .Select(source => source.Key).ToList(); + return SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.IsEmpty + ? new List() + : SourcesWithDiscoveryStatus + .Where(source => source.Value == status) + .Select(source => source.Key) + .ToList(); } #endregion diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 4b53e06663..0a1e6bcad4 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -129,11 +129,12 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete // Sending discovery complete message to IDE SendMessage(testDiscoveryCompletePayload); - var finalDiscoveryCompleteEventArgs = new DiscoveryCompleteEventArgs(_discoveryDataAggregator.TotalTests, - _discoveryDataAggregator.IsAborted, - fullyDiscovered, - partiallyDiscovered, - notDiscovered); + var finalDiscoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( + _discoveryDataAggregator.TotalTests, + _discoveryDataAggregator.IsAborted, + fullyDiscovered, + partiallyDiscovered, + notDiscovered); finalDiscoveryCompleteEventArgs.Metrics = aggregatedDiscoveryDataMetrics; @@ -219,18 +220,11 @@ private void AggregateComingSourcesAsFullyDiscovered(IEnumerable lastC { if (lastChunk == null) return; - IEnumerable lastChunkSources; - // Sometimes we get lastChunk as empty list (when number of tests in project dividable by 10) // Then we will take sources from discoveryCompleteEventArgs coming from testhost - if (lastChunk.Count() == 0) - { - lastChunkSources = discoveryCompleteEventArgs.FullyDiscoveredSources; - } - else - { - lastChunkSources = lastChunk.Select(testcase => testcase.Source); - } + IEnumerable lastChunkSources = !lastChunk.Any() + ? discoveryCompleteEventArgs.FullyDiscoveredSources + : lastChunk.Select(testcase => testcase.Source); _discoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index dc81b5ceb3..dacd1d6d70 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -38,7 +38,7 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager SourcesWithDiscoveryStatus { get; set; } = new ConcurrentDictionary(); + private string _previousSource; + private readonly ConcurrentDictionary _sourcesWithDiscoveryStatus = new(); /// /// Initializes a new instance of the class. /// - public DiscoveryManager(IRequestData requestData) : this(requestData, TestPlatformEventSource.Instance) + public DiscoveryManager(IRequestData requestData) + : this(requestData, TestPlatformEventSource.Instance) { } @@ -355,7 +356,7 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Mark the last sources as fullyDiscovered /// /// Last chunk of testCases which were discovered - private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) + private void MarkTheLastChunkSourcesAsFullyDiscovered(IEnumerable lastChunk) { if (lastChunk == null) return; @@ -363,7 +364,7 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) // When all testcases in project is dividable by 10 then lastChunk is coming as empty // So we need to take the lastSource and mark it as FullyDiscovered - if (lastChunk.Count == 0) lastChunkSources = new List() { _previousSource }; + if (!lastChunk.Any()) lastChunkSources = new List() { _previousSource }; MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } @@ -377,13 +378,13 @@ private void MarkSourceWithStatus(string source, DiscoveryStatus status) { if (source == null) return; - if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) { EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); } else { - SourcesWithDiscoveryStatus[source] = status; + _sourcesWithDiscoveryStatus[source] = status; EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : Marking {source} with {status} status"); } } @@ -402,17 +403,17 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus if (source == null) continue; // It is the first time when we fill our map with sources - if (status == DiscoveryStatus.NotDiscovered) SourcesWithDiscoveryStatus[source] = status; + if (status == DiscoveryStatus.NotDiscovered) _sourcesWithDiscoveryStatus[source] = status; else { - if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) { EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); } else { - SourcesWithDiscoveryStatus[source] = status; + _sourcesWithDiscoveryStatus[source] = status; EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : Marking {source} with {status} status"); } } @@ -424,15 +425,14 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus /// /// discoveryStatus indicates if source was fully/partially/not discovered /// - private IReadOnlyCollection GetFilteredSources(DiscoveryStatus discoveryStatus) + private IReadOnlyList GetFilteredSources(DiscoveryStatus discoveryStatus) { // If by some accident SourcesWithDiscoveryStatus map is empty we will return empty list - if (SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.Count == 0) - { - return new List(); - } - - return SourcesWithDiscoveryStatus.Where(source => source.Value == discoveryStatus) - .Select(source => source.Key).ToList(); + return _sourcesWithDiscoveryStatus == null || _sourcesWithDiscoveryStatus.IsEmpty + ? new List() + : _sourcesWithDiscoveryStatus + .Where(source => source.Value == discoveryStatus) + .Select(source => source.Key) + .ToList(); } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs index b8f2284433..1e14601001 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs @@ -21,13 +21,21 @@ public class DiscoveryCompleteEventArgs : EventArgs /// List of partially discovered sources /// List of not discovered sources public DiscoveryCompleteEventArgs(long totalTests, bool isAborted, - IReadOnlyCollection fullyDiscoveredSources, - IReadOnlyCollection partiallyDiscoveredSources, - IReadOnlyCollection notDiscoveredSources) : this(totalTests, isAborted) + IReadOnlyCollection fullyDiscoveredSources, + IReadOnlyCollection partiallyDiscoveredSources, + IReadOnlyCollection notDiscoveredSources) { - FullyDiscoveredSources = fullyDiscoveredSources; - PartiallyDiscoveredSources = partiallyDiscoveredSources; - NotDiscoveredSources = notDiscoveredSources; + // This event is always raised from the client side, while the total count of tests is maintained + // only at the testhost end. In case of a discovery abort (various reasons including crash), it is + // not possible to get a list of total tests from testhost. Hence we enforce a -1 count. + Debug.Assert((!isAborted || -1 == totalTests), "If discovery request is aborted totalTest should be -1."); + + TotalCount = totalTests; + IsAborted = isAborted; + + FullyDiscoveredSources = fullyDiscoveredSources ?? new List(); + PartiallyDiscoveredSources = partiallyDiscoveredSources ?? new List(); + NotDiscoveredSources = notDiscoveredSources ?? new List(); } /// @@ -36,14 +44,8 @@ public DiscoveryCompleteEventArgs(long totalTests, bool isAborted, /// Total tests which got discovered /// Specifies if discovery has been aborted. public DiscoveryCompleteEventArgs(long totalTests, bool isAborted) + : this(totalTests, isAborted, null, null, null) { - // This event is always raised from the client side, while the total count of tests is maintained - // only at the testhost end. In case of a discovery abort (various reasons including crash), it is - // not possible to get a list of total tests from testhost. Hence we enforce a -1 count. - Debug.Assert((!isAborted || -1 == totalTests), "If discovery request is aborted totalTest should be -1."); - - TotalCount = totalTests; - IsAborted = isAborted; } /// @@ -64,15 +66,15 @@ public DiscoveryCompleteEventArgs(long totalTests, bool isAborted) /// /// Gets the list of sources which were fully discovered. /// - public IReadOnlyCollection FullyDiscoveredSources { get; } = new List(); + public IReadOnlyCollection FullyDiscoveredSources { get; } /// /// Gets the list of sources which were partially discovered (started discover tests, but then discovery aborted). /// - public IReadOnlyCollection PartiallyDiscoveredSources { get; } = new List(); + public IReadOnlyCollection PartiallyDiscoveredSources { get; } /// /// Gets the list of sources which were not discovered at all. /// - public IReadOnlyCollection NotDiscoveredSources { get; } = new List(); + public IReadOnlyCollection NotDiscoveredSources { get; } } diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs index 159b61b435..32210bca7c 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/DiscoverTests.cs @@ -156,10 +156,11 @@ public void DisoverTestUsingEventHandler2ShouldContainAllSourcesAsFullyDiscovere var eventHandler2 = new DiscoveryEventHandler2(); - _vstestConsoleWrapper.DiscoverTests(GetTestAssemblies(), - GetDefaultRunSettings(), - null, - eventHandler2); + _vstestConsoleWrapper.DiscoverTests( + GetTestAssemblies(), + GetDefaultRunSettings(), + null, + eventHandler2); // Assert. Assert.AreEqual(2, eventHandler2.FullyDiscoveredSources.Count); diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs index 4b5c2c496b..bf727f9344 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryEventsHandlerTests.cs @@ -156,7 +156,7 @@ public void HandleDiscoveryCompleteShouldCallConvertToRawMessageAndSendOnceIfDis bool aborted = false; _mockParallelProxyDiscoveryManager.Setup(mp => mp.HandlePartialDiscoveryComplete( - _mockProxyDiscoveryManager.Object, totalTests, null, aborted)).Returns(true); + _mockProxyDiscoveryManager.Object, totalTests, null, aborted)).Returns(true); _mockDataSerializer.Setup(mds => mds.SerializeMessage(MessageType.DiscoveryComplete)).Returns(payload); diff --git a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs index e11e95ddfc..8d8ac8a0ec 100644 --- a/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs +++ b/test/TranslationLayer.UnitTests/VsTestConsoleRequestSenderTests.cs @@ -456,8 +456,8 @@ public void DiscoverTestsShouldCompleteWithSingleFullyDiscoveredSource() DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(testsFound)); - mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())).Callback( - () => _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); + mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())) + .Callback(() => _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); mockHandler.Setup(mh => mh.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) .Callback((DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable tests) => receivedDiscoveryCompleteEventArgs = discoveryCompleteEventArgs); @@ -470,7 +470,7 @@ public void DiscoverTestsShouldCompleteWithSingleFullyDiscoveredSource() } [TestMethod] - public void DiscoverTestsShouldCompleteWithCorrectAbortedValuesIfAbortingWasRequsted() + public void DiscoverTestsShouldCompleteWithCorrectAbortedValuesIfAbortingWasRequested() { // Arrange InitializeCommunication(); @@ -496,8 +496,8 @@ public void DiscoverTestsShouldCompleteWithCorrectAbortedValuesIfAbortingWasRequ DiscoveryCompleteEventArgs receivedDiscoveryCompleteEventArgs = null; _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(testsFound)); - mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())).Callback( - () => _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); + mockHandler.Setup(mh => mh.HandleDiscoveredTests(It.IsAny>())) + .Callback(() => _mockCommunicationManager.Setup(cm => cm.ReceiveMessageAsync(It.IsAny())).Returns(Task.FromResult(discoveryComplete))); mockHandler.Setup(mh => mh.HandleDiscoveryComplete(It.IsAny(), It.IsAny>())) .Callback((DiscoveryCompleteEventArgs discoveryCompleteEventArgs, IEnumerable tests) => receivedDiscoveryCompleteEventArgs = discoveryCompleteEventArgs); From 46d5eef124320272bb1c1def0213d213acea9345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 14 Feb 2022 15:56:44 +0100 Subject: [PATCH 21/31] Address some code review comments --- .../Discovery/DiscoveryRequest.cs | 2 +- .../Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs | 8 ++++---- .../PublicAPI/PublicAPI.Unshipped.txt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index bb6b2b8391..2bda3e602e 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -68,7 +68,7 @@ public void DiscoverAsync() { if (_disposed) { - throw new ObjectDisposedException("DiscoveryRequest"); + throw new ObjectDisposedException(nameof(DiscoveryRequest)); } // Reset the discovery completion event diff --git a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs index f57d698742..337b4139ff 100644 --- a/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs +++ b/src/Microsoft.TestPlatform.Common/Interfaces/Engine/ClientProtocol/DiscoveryStatus.cs @@ -9,9 +9,9 @@ namespace Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; public enum DiscoveryStatus { /// - /// Indicates that source was fully discovered. + /// Indicates the sources which were not touched during discovery. /// - FullyDiscovered, + NotDiscovered, /// /// Indicates that we started discovery of the source but something happened (cancel/abort) and we stopped processing it. @@ -19,7 +19,7 @@ public enum DiscoveryStatus PartiallyDiscovered, /// - /// Indicates the sources which were not touched during discovery. + /// Indicates that source was fully discovered. /// - NotDiscovered, + FullyDiscovered, } diff --git a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt index ec98416753..173c7c1cd4 100644 --- a/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Common/PublicAPI/PublicAPI.Unshipped.txt @@ -10,6 +10,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IParallelProxyDiscoveryMa Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.IProxyDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.TesthostProtocol.IDiscoveryManager.Abort(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestDiscoveryEventsHandler2 eventHandler) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus -Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.NotDiscovered = 0 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.PartiallyDiscovered = 1 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus +Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus.FullyDiscovered = 2 -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine.DiscoveryStatus From 56ab6778aff0d77ebbf015e88c180c12bda86bf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 14 Feb 2022 17:32:49 +0100 Subject: [PATCH 22/31] Update src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs Co-authored-by: Medeni Baykal <433724+Haplois@users.noreply.github.com> --- src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index 2bda3e602e..cdf18c07f1 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -154,7 +154,7 @@ public void AbortWithEventHandler() { if (_disposed) { - throw new ObjectDisposedException("DiscoveryRequest"); + throw new ObjectDisposedException(nameof(DiscoveryRequest)); } if (DiscoveryInProgress) From 5271c97caa09cf51fc3858059eab7ed8d288855e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 15 Feb 2022 18:47:44 +0100 Subject: [PATCH 23/31] Address part of the review comments --- .../JsonDataSerializer.cs | 13 ++++- .../Messages/DiscoveryCompletePayload.cs | 6 +-- .../PublicAPI/PublicAPI.Unshipped.txt | 8 +-- .../ParallelDiscoveryDataAggregator.cs | 2 +- .../ParallelDiscoveryEventsHandler.cs | 42 ++++++++------- .../Parallel/ParallelProxyDiscoveryManager.cs | 5 +- .../Client/ProxyDiscoveryManager.cs | 4 +- .../Discovery/DiscoveryManager.cs | 54 ++++++++++++------- .../Events/DiscoveryCompleteEventArgs.cs | 12 ++--- .../PublicAPI/PublicAPI.Unshipped.txt | 13 +++-- .../PublicAPI/net/PublicAPI.Unshipped.txt | 2 +- .../EventHandler/DiscoveryEventHandler.cs | 6 +-- 12 files changed, 102 insertions(+), 65 deletions(-) diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs index 2078612b98..32f288f8dd 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/JsonDataSerializer.cs @@ -206,6 +206,15 @@ private JsonSerializer GetPayloadSerializer(int? version) version = 1; } + // 0: the original protocol with no versioning (Message). It is used during negotiation. + // 1: new protocol with versioning (VersionedMessage). + // 2: changed serialization because the serialization of properties in bag was too verbose, + // so common properties are considered built-in and serialized without type info. + // 3: introduced because of changes to allow attaching debugger to external process. + // 4: introduced because 3 did not update this table and ended up using the serializer for protocol v1, + // which is extremely slow. We negotiate 2 or 4, but never 3 unless the flag above is set. + // 5: ??? + // 6: accepts abort and cancel with handlers that report the status. return version switch { // 0 is used during negotiation. @@ -215,8 +224,8 @@ private JsonSerializer GetPayloadSerializer(int? version) // env variable. 0 or 1 or 3 => s_payloadSerializer, 2 or 4 or 5 or 6 => s_payloadSerializer2, - _ => throw new NotSupportedException($"Protocol version {version} is not supported. " + - "Ensure it is compatible with the latest serializer or add a new one."), + _ => throw new NotSupportedException($"Protocol version {version} is not supported. " + + "Ensure it is compatible with the latest serializer or add a new one."), }; } } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs index 864b78f2ff..d0c98d24df 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/Messages/DiscoveryCompletePayload.cs @@ -35,15 +35,15 @@ public class DiscoveryCompletePayload /// /// Gets or sets list of sources which were fully discovered. /// - public IReadOnlyCollection FullyDiscoveredSources { get; set; } = new List(); + public IList FullyDiscoveredSources { get; set; } = new List(); /// /// Gets or sets list of sources which were partially discovered (started discover tests, but then discovery aborted). /// - public IReadOnlyCollection PartiallyDiscoveredSources { get; set; } = new List(); + public IList PartiallyDiscoveredSources { get; set; } = new List(); /// /// Gets or sets list of sources which were not discovered at all. /// - public IReadOnlyCollection NotDiscoveredSources { get; set; } = new List(); + public IList NotDiscoveredSources { get; set; } = new List(); } diff --git a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt index 1c90267bfa..47a461296e 100644 --- a/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.CommunicationUtilities/PublicAPI/PublicAPI.Unshipped.txt @@ -1,8 +1,8 @@ Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.Interfaces.ITestRequestSender.SendDiscoveryAbort() -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.get -> System.Collections.Generic.IList Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.FullyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.get -> System.Collections.Generic.IList Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.NotDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.get -> System.Collections.Generic.IList Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.ObjectModel.DiscoveryCompletePayload.PartiallyDiscoveredSources.set -> void -Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void \ No newline at end of file +Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TestRequestSender.SendDiscoveryAbort() -> void diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index da11c1d885..e3bc57c684 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -186,7 +186,7 @@ internal void AggregateIsMessageSent(bool isMessageSent) /// /// Status to filter /// - internal ICollection GetSourcesWithStatus(DiscoveryStatus status) + internal List GetSourcesWithStatus(DiscoveryStatus status) { return SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.IsEmpty ? new List() diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index 0a1e6bcad4..61754a0ea5 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -96,9 +96,9 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete if (parallelDiscoveryComplete) { - var fullyDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered) as IReadOnlyCollection; - var partiallyDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered) as IReadOnlyCollection; - var notDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered) as IReadOnlyCollection; + var fullyDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered); + var partiallyDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered); + var notDiscovered = _discoveryDataAggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered); // As we immediately return results to IDE in case of aborting // we need to set isAborted = true and totalTests = -1 @@ -127,7 +127,7 @@ public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs discoveryComplete testDiscoveryCompletePayload.Metrics = aggregatedDiscoveryDataMetrics; // Sending discovery complete message to IDE - SendMessage(testDiscoveryCompletePayload); + ConvertToRawMessageAndSend(testDiscoveryCompletePayload); var finalDiscoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( _discoveryDataAggregator.TotalTests, @@ -193,20 +193,22 @@ private void ConvertToRawMessageAndSend(string messageType, object payload) /// /// Discovery aggregator to know if we already sent this message /// Discovery complete payload to send - private void SendMessage(DiscoveryCompletePayload testDiscoveryCompletePayload) + private void ConvertToRawMessageAndSend(DiscoveryCompletePayload testDiscoveryCompletePayload) { - // In case of abort scenario, we need to send raw message to IDE only once after abortion. - // All other testhosts which will finish after shouldn't send raw message - if (!_discoveryDataAggregator.IsMessageSent) + // When we abort we should send raw message to IDE only once. + // All other testhosts which will finish after shouldn't send abort raw message. + if (_discoveryDataAggregator.IsMessageSent) { - lock (_sendMessageLock) + return; + } + + lock (_sendMessageLock) + { + if (!_discoveryDataAggregator.IsMessageSent) { - if (!_discoveryDataAggregator.IsMessageSent) - { - // we have to send raw messages as we block the discovery complete actual raw messages - ConvertToRawMessageAndSend(MessageType.DiscoveryComplete, testDiscoveryCompletePayload); - _discoveryDataAggregator.AggregateIsMessageSent(true); - } + // we have to send raw messages as we block the discovery complete actual raw messages + ConvertToRawMessageAndSend(MessageType.DiscoveryComplete, testDiscoveryCompletePayload); + _discoveryDataAggregator.AggregateIsMessageSent(true); } } } @@ -218,10 +220,14 @@ private void SendMessage(DiscoveryCompletePayload testDiscoveryCompletePayload) /// Last chunk of discovered test cases private void AggregateComingSourcesAsFullyDiscovered(IEnumerable lastChunk, DiscoveryCompleteEventArgs discoveryCompleteEventArgs) { - if (lastChunk == null) return; + if (lastChunk is null) + { + return; + } - // Sometimes we get lastChunk as empty list (when number of tests in project dividable by 10) - // Then we will take sources from discoveryCompleteEventArgs coming from testhost + // Sometimes we get lastChunk as empty list (when number of tests in project dividable by + // the chunk size, e.g. 100 tests and 10 chunk size). + // Then we will take sources from discoveryCompleteEventArgs coming from testhost. IEnumerable lastChunkSources = !lastChunk.Any() ? discoveryCompleteEventArgs.FullyDiscoveredSources : lastChunk.Select(testcase => testcase.Source); diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index d128e7f413..c9e09388ad 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -255,7 +255,10 @@ private void DiscoverTestsOnConcurrentManager(IProxyDiscoveryManager proxyDiscov /// Sources which will be discovered private void MarkAllSourcesAsNotDiscovered(IEnumerable sources) { - if (sources == null || sources.Count() == 0) return; + if (sources is null || !sources.Any()) + { + return; + } lock (_enumeratorLockObject) { diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs index 60c2a87045..d6c8586707 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/ProxyDiscoveryManager.cs @@ -199,12 +199,12 @@ public void Abort() public void Abort(ITestDiscoveryEventsHandler2 eventHandler) { // Do nothing if the proxy is not initialized yet. - if (_proxyOperationManager == null) + if (_proxyOperationManager is null) { return; } - if (_baseTestDiscoveryEventsHandler == null) + if (_baseTestDiscoveryEventsHandler is null) { _baseTestDiscoveryEventsHandler = eventHandler; } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 436651e64d..5be95776b9 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -141,8 +141,8 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve if (lastChunk != null) { UpdateTestCases(lastChunk, _discoveryCriteria.Package); - /* When discovery is complete we will have case that the last discovered source is still marked as partiallyDiscovered. - * So we need to mark it as fullyDiscovered.*/ + // When discovery is complete then the last discovered source is still marked + // as partially discovered, so we need to mark it as fully discovered. MarkTheLastChunkSourcesAsFullyDiscovered(lastChunk); } @@ -358,13 +358,19 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Last chunk of testCases which were discovered private void MarkTheLastChunkSourcesAsFullyDiscovered(IEnumerable lastChunk) { - if (lastChunk == null) return; + if (lastChunk is null) + { + return; + } var lastChunkSources = lastChunk.Select(testcase => testcase.Source); // When all testcases in project is dividable by 10 then lastChunk is coming as empty // So we need to take the lastSource and mark it as FullyDiscovered - if (!lastChunk.Any()) lastChunkSources = new List() { _previousSource }; + if (!lastChunk.Any()) + { + lastChunkSources = new List() { _previousSource }; + } MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } @@ -376,7 +382,10 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IEnumerable last /// DiscoveryStatus to mark for source private void MarkSourceWithStatus(string source, DiscoveryStatus status) { - if (source == null) return; + if (source is null) + { + return; + } if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) { @@ -396,26 +405,33 @@ private void MarkSourceWithStatus(string source, DiscoveryStatus status) /// DiscoveryStatus to mark for list of sources private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus status) { - if (sources == null || sources.Count() == 0) return; + if (sources is null || !sources.Any()) + { + return; + } foreach (var source in sources) { - if (source == null) continue; + if (source is null) + { + continue; + } // It is the first time when we fill our map with sources - if (status == DiscoveryStatus.NotDiscovered) _sourcesWithDiscoveryStatus[source] = status; + if (status == DiscoveryStatus.NotDiscovered) + { + _sourcesWithDiscoveryStatus[source] = status; + continue; + } + if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) + { + EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus: SourcesWithDiscoveryStatus does not contain {source}."); + } else { - if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) - { - EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); - } - else - { - _sourcesWithDiscoveryStatus[source] = status; - EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus : Marking {source} with {status} status"); - } + _sourcesWithDiscoveryStatus[source] = status; + EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus: Marking {source} with {status} status."); } } } @@ -425,10 +441,10 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus /// /// discoveryStatus indicates if source was fully/partially/not discovered /// - private IReadOnlyList GetFilteredSources(DiscoveryStatus discoveryStatus) + private List GetFilteredSources(DiscoveryStatus discoveryStatus) { // If by some accident SourcesWithDiscoveryStatus map is empty we will return empty list - return _sourcesWithDiscoveryStatus == null || _sourcesWithDiscoveryStatus.IsEmpty + return _sourcesWithDiscoveryStatus is null || _sourcesWithDiscoveryStatus.IsEmpty ? new List() : _sourcesWithDiscoveryStatus .Where(source => source.Value == discoveryStatus) diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs index 1e14601001..28e3dd067a 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Events/DiscoveryCompleteEventArgs.cs @@ -21,9 +21,9 @@ public class DiscoveryCompleteEventArgs : EventArgs /// List of partially discovered sources /// List of not discovered sources public DiscoveryCompleteEventArgs(long totalTests, bool isAborted, - IReadOnlyCollection fullyDiscoveredSources, - IReadOnlyCollection partiallyDiscoveredSources, - IReadOnlyCollection notDiscoveredSources) + IList fullyDiscoveredSources, + IList partiallyDiscoveredSources, + IList notDiscoveredSources) { // This event is always raised from the client side, while the total count of tests is maintained // only at the testhost end. In case of a discovery abort (various reasons including crash), it is @@ -66,15 +66,15 @@ public DiscoveryCompleteEventArgs(long totalTests, bool isAborted) /// /// Gets the list of sources which were fully discovered. /// - public IReadOnlyCollection FullyDiscoveredSources { get; } + public IList FullyDiscoveredSources { get; set; } /// /// Gets the list of sources which were partially discovered (started discover tests, but then discovery aborted). /// - public IReadOnlyCollection PartiallyDiscoveredSources { get; } + public IList PartiallyDiscoveredSources { get; set; } /// /// Gets the list of sources which were not discovered at all. /// - public IReadOnlyCollection NotDiscoveredSources { get; } + public IList NotDiscoveredSources { get; set; } } diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt index eb1f6098ef..4482aee9b1 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt @@ -1,8 +1,11 @@ const Microsoft.VisualStudio.TestPlatform.ObjectModel.Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport = 6 -> int -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.DiscoveryCompleteEventArgs(long totalTests, bool isAborted, System.Collections.Generic.IReadOnlyCollection fullyDiscoveredSources, System.Collections.Generic.IReadOnlyCollection partiallyDiscoveredSources, System.Collections.Generic.IReadOnlyCollection notDiscoveredSources) -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.FullyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.NotDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.PartiallyDiscoveredSources.get -> System.Collections.Generic.IReadOnlyCollection +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.DiscoveryCompleteEventArgs(long totalTests, bool isAborted, System.Collections.Generic.IList fullyDiscoveredSources, System.Collections.Generic.IList partiallyDiscoveredSources, System.Collections.Generic.IList notDiscoveredSources) -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.FullyDiscoveredSources.get -> System.Collections.Generic.IList +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.FullyDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.NotDiscoveredSources.get -> System.Collections.Generic.IList +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.NotDiscoveredSources.set -> void +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.PartiallyDiscoveredSources.get -> System.Collections.Generic.IList +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCompleteEventArgs.PartiallyDiscoveredSources.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.DiscoveryCriteria(System.Collections.Generic.IEnumerable sources, long frequencyOfDiscoveredTestsEvent, System.TimeSpan discoveredTestEventTimeout, string runSettings, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo testSessionInfo) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.TestSessionInfo.get -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.TestSessionInfo.set -> void @@ -36,4 +39,4 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEv Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs.StopTestSessionCompleteEventArgs() -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs.StopTestSessionCompleteEventArgs(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo testSessionInfo) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs.TestSessionInfo.get -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs.TestSessionInfo.set -> void \ No newline at end of file +Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs.TestSessionInfo.set -> void diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Unshipped.txt index 5f282702bb..e02abfc9b0 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/net/PublicAPI.Unshipped.txt @@ -1 +1 @@ - \ No newline at end of file + diff --git a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs index ff226444e7..902b880772 100644 --- a/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs +++ b/test/Microsoft.TestPlatform.AcceptanceTests/TranslationLayerTests/EventHandler/DiscoveryEventHandler.cs @@ -70,9 +70,9 @@ public class DiscoveryEventHandler2 : ITestDiscoveryEventsHandler2 /// public List DiscoveredTestCases { get; } - public IReadOnlyCollection FullyDiscoveredSources { get; private set; } - public IReadOnlyCollection PartiallyDiscoveredSources { get; private set; } - public IReadOnlyCollection NotDiscoveredSources { get; private set; } + public IList FullyDiscoveredSources { get; private set; } + public IList PartiallyDiscoveredSources { get; private set; } + public IList NotDiscoveredSources { get; private set; } public List TestMessages; From 226544d2ae3b8ad5b8f1ef2792b53f50540beedc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 15 Feb 2022 19:26:26 +0100 Subject: [PATCH 24/31] Simpler API --- .../DesignMode/DesignModeClient.cs | 13 +----- .../Discovery/DiscoveryRequest.cs | 40 ++++++------------- .../PublicAPI/PublicAPI.Unshipped.txt | 2 - .../RequestHelper/ITestRequestManager.cs | 5 --- .../Client/Interfaces/IDiscoveryRequest.cs | 5 --- .../PublicAPI/PublicAPI.Unshipped.txt | 1 - .../TestPlatformHelpers/TestRequestManager.cs | 7 ---- .../Discovery/DiscoveryRequestTests.cs | 2 +- 8 files changed, 15 insertions(+), 60 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs index ee9f40fe73..7924e7d7c9 100644 --- a/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs +++ b/src/Microsoft.TestPlatform.Client/DesignMode/DesignModeClient.cs @@ -36,7 +36,7 @@ public class DesignModeClient : IDesignModeClient private readonly ICommunicationManager _communicationManager; private readonly IDataSerializer _dataSerializer; - private readonly ProtocolConfig _protocolConfig = ObjectModel.Constants.DefaultProtocolConfig; + private readonly ProtocolConfig _protocolConfig = Constants.DefaultProtocolConfig; private readonly IEnvironment _platformEnvironment; private readonly TestSessionMessageLogger _testSessionMessageLogger; private readonly object _lockObject = new(); @@ -223,16 +223,7 @@ private void ProcessRequests(ITestRequestManager testRequestManager) case MessageType.CancelDiscovery: { - // If testhost has old version, we should use old cancel logic - // to be consistent and not create regression issues - if (_protocolConfig.Version < ObjectModel.Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) - { - testRequestManager.CancelDiscovery(); - } - else - { - testRequestManager.CancelDiscoveryWithEventHandler(); - } + testRequestManager.CancelDiscovery(); break; } diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index cdf18c07f1..a17839e3b5 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -24,6 +24,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery; public sealed class DiscoveryRequest : IDiscoveryRequest, ITestDiscoveryEventsHandler2 { private readonly IDataSerializer _dataSerializer; + private readonly ProtocolConfig _protocolConfig = Constants.DefaultProtocolConfig; /// /// Initializes a new instance of the class. @@ -110,12 +111,21 @@ public void Abort() { if (_disposed) { - throw new ObjectDisposedException("DiscoveryRequest"); + throw new ObjectDisposedException(nameof(DiscoveryRequest)); } if (DiscoveryInProgress) { - DiscoveryManager.Abort(); + // If testhost has old version, we should use old cancel logic + // to be consistent and not create regression issues + if (_protocolConfig.Version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) + { + DiscoveryManager.Abort(); + } + else + { + DiscoveryManager.Abort(this); + } } else { @@ -145,32 +155,6 @@ bool IRequest.WaitForCompletion(int timeout) return _discoveryCompleted == null || _discoveryCompleted.WaitOne(timeout); } - /// - public void AbortWithEventHandler() - { - EqtTrace.Verbose("DiscoveryRequest.AbortWithEventHandler: Aborting."); - - lock (_syncObject) - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(DiscoveryRequest)); - } - - if (DiscoveryInProgress) - { - DiscoveryManager.Abort(this); - } - else - { - EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: No operation to abort."); - return; - } - } - - EqtTrace.Info("DiscoveryRequest.AbortWithEventHandler: Aborted."); - } - /// /// Raised when the test discovery starts. /// diff --git a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt index 2abbcd2de4..111bb22aa1 100644 --- a/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.Client/PublicAPI/PublicAPI.Unshipped.txt @@ -1,3 +1 @@ -Microsoft.VisualStudio.TestPlatform.Client.Discovery.DiscoveryRequest.AbortWithEventHandler() -> void -Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.CancelDiscoveryWithEventHandler() -> void Microsoft.VisualStudio.TestPlatform.Client.RequestHelper.ITestRequestManager.StopTestSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.Payloads.StopTestSessionPayload payload, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler eventsHandler, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ProtocolConfig protocolConfig) -> void diff --git a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs index 6674053db3..2d501c284e 100644 --- a/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs +++ b/src/Microsoft.TestPlatform.Client/RequestHelper/ITestRequestManager.cs @@ -115,11 +115,6 @@ void StopTestSession( /// void CancelDiscovery(); - /// - /// Cancels the current discovery request with discovery complete event handler. - /// - void CancelDiscoveryWithEventHandler(); - /// /// Cancels the current test run attachments processing request. /// diff --git a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs index 952a170c98..2ecb088dda 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.ObjectModel/Client/Interfaces/IDiscoveryRequest.cs @@ -50,9 +50,4 @@ DiscoveryCriteria DiscoveryCriteria /// Aborts the discovery request /// void Abort(); - - /// - /// Aborts the discovery request with event handler. - /// - void AbortWithEventHandler(); } diff --git a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt index 4482aee9b1..da26b150f1 100644 --- a/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Microsoft.TestPlatform.ObjectModel/PublicAPI/PublicAPI.Unshipped.txt @@ -11,7 +11,6 @@ Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.TestSes Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryCriteria.TestSessionInfo.set -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryRequestPayload.TestSessionInfo.get -> Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.TestSessionInfo Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.DiscoveryRequestPayload.TestSessionInfo.set -> void -Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IDiscoveryRequest.AbortWithEventHandler() -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestPlatform.StartTestSession(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.IRequestData requestData, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StartTestSessionCriteria criteria, Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler eventsHandler) -> bool Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler.HandleStartTestSessionComplete(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StartTestSessionCompleteEventArgs eventArgs) -> void Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.ITestSessionEventsHandler.HandleStopTestSessionComplete(Microsoft.VisualStudio.TestPlatform.ObjectModel.Client.StopTestSessionCompleteEventArgs eventArgs) -> void diff --git a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs index a459b87e2c..24df0aed2e 100644 --- a/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs +++ b/src/vstest.console/TestPlatformHelpers/TestRequestManager.cs @@ -572,13 +572,6 @@ public void CancelDiscovery() _currentDiscoveryRequest?.Abort(); } - /// - public void CancelDiscoveryWithEventHandler() - { - EqtTrace.Info("TestRequestManager.CancelDiscoveryWithEventHandler: Sending cancel request."); - _currentDiscoveryRequest?.AbortWithEventHandler(); - } - /// public void AbortTestRun() { diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs index 2923cf06cc..3b27e13102 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs @@ -106,7 +106,7 @@ public void AbortWithEventHandlerIfDiscoveryIsinProgressShouldCallDiscoveryManag _discoveryRequest.DiscoverAsync(); var eventsHandler = _discoveryRequest as ITestDiscoveryEventsHandler2; - _discoveryRequest.AbortWithEventHandler(); + _discoveryRequest.Abort(); _discoveryManager.Verify(dm => dm.Abort(eventsHandler), Times.Once); } From 485cf0bc827fb061c46bd9599ee415a08bf539d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 15 Feb 2022 19:47:51 +0100 Subject: [PATCH 25/31] Rework method --- .../Parallel/ParallelDiscoveryDataAggregator.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index 1fef164a1d..ca0d2dbc56 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -140,13 +140,14 @@ public void AggregateDiscoveryDataMetrics(IDictionary metrics) /// Fully discovered source internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources, DiscoveryStatus status) { - if (sources == null || sources.Count() == 0) return; - - foreach (var source in sources) + if (sources is null || !sources.Any()) { - if (status == DiscoveryStatus.NotDiscovered) SourcesWithDiscoveryStatus[source] = status; + return; + } - if (!SourcesWithDiscoveryStatus.ContainsKey(source)) + foreach (var source in sources) + { + if (!SourcesWithDiscoveryStatus.ContainsKey(source) && status != DiscoveryStatus.NotDiscovered) { EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " + $"{source} is not present in SourcesWithDiscoveryStatus dictionary."); From 547c9f22faf43b0aec21b8028ee7310ac4f0f5ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 15 Feb 2022 20:38:23 +0100 Subject: [PATCH 26/31] More refactorings --- .../ParallelDiscoveryDataAggregator.cs | 2 +- .../Discovery/DiscoveryManager.cs | 55 +++++-------------- 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index ca0d2dbc56..a2db8fcc7b 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -146,7 +146,7 @@ internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources } foreach (var source in sources) - { + { if (!SourcesWithDiscoveryStatus.ContainsKey(source) && status != DiscoveryStatus.NotDiscovered) { EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index b51a8f7435..15c74cbe59 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -109,7 +109,7 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve foreach (var kvp in discoveryCriteria.AdapterSourceMap) { var verifiedSources = GetValidSources(kvp.Value, _sessionMessageLogger, discoveryCriteria.Package); - if (verifiedSources.Any()) + if (verifiedSources.Count > 0) { verifiedExtensionSourceMap.Add(kvp.Key, kvp.Value); // Mark all sources as NotDiscovered before actual discovery starts @@ -117,7 +117,6 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve } } - // If there are sources to discover if (verifiedExtensionSourceMap.Any()) { @@ -230,7 +229,7 @@ private void OnReportTestCases(IEnumerable testCases) /// logger /// package /// The list of verified sources. - internal static IEnumerable GetValidSources(IEnumerable sources, IMessageLogger logger, string package) + internal static HashSet GetValidSources(IEnumerable sources, IMessageLogger logger, string package) { Debug.Assert(sources != null, "sources"); var verifiedSources = new HashSet(StringComparer.OrdinalIgnoreCase); @@ -274,7 +273,7 @@ void SendWarning() } // No valid source is found => we cannot discover. - if (!verifiedSources.Any()) + if (verifiedSources.Count == 0) { var sourcesString = string.Join(",", sources.ToArray()); var errorMessage = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.NoValidSourceFoundForDiscovery, sourcesString); @@ -330,20 +329,23 @@ private static void UpdateTestCases(IEnumerable testCases, string pack /// List of testCases which were already discovered private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCases) { - if (testCases == null || testCases.Count() == 0) return; + if (testCases is null || !testCases.Any()) + { + return; + } foreach (var testCase in testCases) { string currentSource = testCase.Source; - // If it is the first list of testCases which was discovered, we mark sources as partiallyDiscovered. - // Or if current source is the same as previous we again mark them as partiallyDiscovered for consistency + // If it is the first list of testCases which was discovered or if current source + // is the same as previous we mark them as partially discovered. if (_previousSource is null || _previousSource == currentSource) { MarkSourceWithStatus(currentSource, DiscoveryStatus.PartiallyDiscovered); } - // If source is changed, we need to mark previous source as already fullyDiscovered - // and currentSource should be partiallyDiscovered + // If source is changed, we need to mark previous source as already fully discovered + // and currentSource as partially discovered. else if (currentSource != _previousSource) { MarkSourceWithStatus(_previousSource, DiscoveryStatus.FullyDiscovered); @@ -358,13 +360,8 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Mark the last sources as fullyDiscovered /// /// Last chunk of testCases which were discovered - private void MarkTheLastChunkSourcesAsFullyDiscovered(IEnumerable lastChunk) + private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) { - if (lastChunk is null) - { - return; - } - var lastChunkSources = lastChunk.Select(testcase => testcase.Source); // When all testcases in project is dividable by 10 then lastChunk is coming as empty @@ -383,22 +380,7 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IEnumerable last /// Sources to mark /// DiscoveryStatus to mark for source private void MarkSourceWithStatus(string source, DiscoveryStatus status) - { - if (source is null) - { - return; - } - - if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) - { - EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : SourcesWithDiscoveryStatus does not contain {source}"); - } - else - { - _sourcesWithDiscoveryStatus[source] = status; - EqtTrace.Warning($"DiscoveryManager.MarkSourceWithStatus : Marking {source} with {status} status"); - } - } + => MarkSourcesWithStatus(new[] { source }, status); /// /// Mark sources with particular DiscoveryStatus @@ -419,21 +401,14 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus continue; } - // It is the first time when we fill our map with sources - if (status == DiscoveryStatus.NotDiscovered) - { - _sourcesWithDiscoveryStatus[source] = status; - continue; - } - - if (!_sourcesWithDiscoveryStatus.ContainsKey(source)) + if (status != DiscoveryStatus.NotDiscovered && !_sourcesWithDiscoveryStatus.ContainsKey(source)) { EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus: SourcesWithDiscoveryStatus does not contain {source}."); } else { _sourcesWithDiscoveryStatus[source] = status; - EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus: Marking {source} with {status} status."); + EqtTrace.Info($"DiscoveryManager.MarkSourcesWithStatus: Marking {source} with {status} status."); } } } From 373510a2bb8f9e266f7f20c5e43a4f2e9082374d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 16 Feb 2022 15:12:52 +0100 Subject: [PATCH 27/31] Fix test --- .../Discovery/DiscoveryRequest.cs | 2 +- .../Discovery/DiscoveryRequestTests.cs | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index f230a36a95..ee72fb3da4 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -26,7 +26,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery; public sealed class DiscoveryRequest : IDiscoveryRequest, ITestDiscoveryEventsHandler2 { private readonly IDataSerializer _dataSerializer; - private readonly ProtocolConfig _protocolConfig = Constants.DefaultProtocolConfig; + internal /* for testing purposes */ readonly ProtocolConfig _protocolConfig = Constants.DefaultProtocolConfig; /// /// Initializes a new instance of the class. diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs index 1d7840da54..94a72953de 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs @@ -91,25 +91,33 @@ public void AbortIfDiscoveryRequestDisposedShouldThrowObjectDisposedException() Assert.ThrowsException(() => _discoveryRequest.Abort()); } - [TestMethod] - public void AbortIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbort() + [DataTestMethod] + [DataRow(0)] + [DataRow(1)] + [DataRow(2)] + [DataRow(3)] + [DataRow(4)] + [DataRow(5)] + public void AbortIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbort(int version) { // Just to set the IsDiscoveryInProgress flag _discoveryRequest.DiscoverAsync(); + // Set the protocol version to a version not supporting new abort overload. + _discoveryRequest._protocolConfig.Version = version; + _discoveryRequest.Abort(); _discoveryManager.Verify(dm => dm.Abort(), Times.Once); } [TestMethod] - public void AbortWithEventHandlerIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbortWithEventHandler() + public void AbortIfDiscoveryIsinProgressShouldAndSufficientProtocolVersionCallsDiscoveryManagerAbortThis() { // Just to set the IsDiscoveryInProgress flag _discoveryRequest.DiscoverAsync(); - var eventsHandler = _discoveryRequest as ITestDiscoveryEventsHandler2; _discoveryRequest.Abort(); - _discoveryManager.Verify(dm => dm.Abort(eventsHandler), Times.Once); + _discoveryManager.Verify(dm => dm.Abort(_discoveryRequest), Times.Once); } [TestMethod] From 473360d2942348b048a1604fab4708783eae3b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 16 Feb 2022 15:13:09 +0100 Subject: [PATCH 28/31] Remove duplications and race issues --- .../ParallelDiscoveryDataAggregator.cs | 39 ++-------- .../ParallelDiscoveryEventsHandler.cs | 6 +- .../Parallel/ParallelProxyDiscoveryManager.cs | 32 +------- .../Discovery/DiscoveryManager.cs | 75 ++++++++++--------- .../ParallelDiscoveryDataAggregatorTests.cs | 4 +- 5 files changed, 51 insertions(+), 105 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index a2db8fcc7b..af8b4ca3c1 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.Parallel; using Common.Telemetry; -using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Discovery; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Engine; using System; @@ -44,7 +44,7 @@ public ParallelDiscoveryDataAggregator() /// /// Dictionary which stores source with corresponding discoveryStatus /// - internal ConcurrentDictionary SourcesWithDiscoveryStatus { get; } = new(); + private readonly ConcurrentDictionary _sourcesWithDiscoveryStatus = new(); /// /// Indicates if discovery complete payload already sent back to IDE @@ -138,29 +138,8 @@ public void AggregateDiscoveryDataMetrics(IDictionary metrics) /// Aggregate the source as fully discovered /// /// Fully discovered source - internal void AggregateTheSourcesWithDiscoveryStatus(IEnumerable sources, DiscoveryStatus status) - { - if (sources is null || !sources.Any()) - { - return; - } - - foreach (var source in sources) - { - if (!SourcesWithDiscoveryStatus.ContainsKey(source) && status != DiscoveryStatus.NotDiscovered) - { - EqtTrace.Warning("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " - + $"{source} is not present in SourcesWithDiscoveryStatus dictionary."); - } - else - { - SourcesWithDiscoveryStatus[source] = status; - - EqtTrace.Info("ParallelDiscoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus: " - + $"{source} is marked with {status} status."); - } - } - } + internal void MarkSourcesWithStatus(ICollection sources, DiscoveryStatus status) + => DiscoveryManager.MarkSourcesWithStatus(sources, status, _sourcesWithDiscoveryStatus); /// /// Aggregates the value indicating if we already sent message to IDE. @@ -177,13 +156,5 @@ internal void AggregateIsMessageSent(bool isMessageSent) /// Status to filter /// internal List GetSourcesWithStatus(DiscoveryStatus status) - { - return SourcesWithDiscoveryStatus == null || SourcesWithDiscoveryStatus.IsEmpty - ? new List() - : SourcesWithDiscoveryStatus - .Where(source => source.Value == status) - .Select(source => source.Key) - .ToList(); - } - + => DiscoveryManager.GetSourcesWithStatus(status, _sourcesWithDiscoveryStatus); } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs index be8eb642a3..8faa60f75c 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryEventsHandler.cs @@ -230,10 +230,10 @@ private void AggregateComingSourcesAsFullyDiscovered(IEnumerable lastC // Sometimes we get lastChunk as empty list (when number of tests in project dividable by // the chunk size, e.g. 100 tests and 10 chunk size). // Then we will take sources from discoveryCompleteEventArgs coming from testhost. - IEnumerable lastChunkSources = !lastChunk.Any() + var lastChunkSources = !lastChunk.Any() ? discoveryCompleteEventArgs.FullyDiscoveredSources - : lastChunk.Select(testcase => testcase.Source); + : lastChunk.Select(testcase => testcase.Source).ToList(); - _discoveryDataAggregator.AggregateTheSourcesWithDiscoveryStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); + _discoveryDataAggregator.MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs index ef1c3e7033..114e6b0c44 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelProxyDiscoveryManager.cs @@ -25,8 +25,6 @@ internal class ParallelProxyDiscoveryManager : ParallelOperationManager /// LockObject to update discovery status in parallel /// private readonly object _discoveryStatusLockObject = new(); - private readonly object _enumeratorLockObject = new(); - - #endregion - public ParallelProxyDiscoveryManager(IRequestData requestData, Func actualProxyManagerCreator, int parallelLevel, bool sharedHosts) : this(requestData, actualProxyManagerCreator, JsonDataSerializer.Instance, parallelLevel, sharedHosts) { @@ -91,7 +81,7 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve _currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator(); // Marking all sources as not discovered before starting actual discovery - MarkAllSourcesAsNotDiscovered(discoveryCriteria.Sources); + _currentDiscoveryDataAggregator.MarkSourcesWithStatus(discoveryCriteria.Sources.ToList(), DiscoveryStatus.NotDiscovered); DiscoverTestsPrivate(eventHandler); } @@ -250,24 +240,4 @@ private void DiscoverTestsOnConcurrentManager(IProxyDiscoveryManager proxyDiscov EqtTrace.Verbose("ProxyParallelDiscoveryManager: No sources available for discovery."); } - - /// - /// Mark all sources as not discovered before starting actual discovery - /// - /// Sources which will be discovered - private void MarkAllSourcesAsNotDiscovered(IEnumerable sources) - { - if (sources is null || !sources.Any()) - { - return; - } - - lock (_enumeratorLockObject) - { - foreach (string source in sources) - { - _currentDiscoveryDataAggregator.SourcesWithDiscoveryStatus[source] = DiscoveryStatus.NotDiscovered; - } - } - } } diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs index 15c74cbe59..33796d34f7 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Discovery/DiscoveryManager.cs @@ -113,7 +113,7 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve { verifiedExtensionSourceMap.Add(kvp.Key, kvp.Value); // Mark all sources as NotDiscovered before actual discovery starts - MarkSourcesWithStatus(verifiedSources, DiscoveryStatus.NotDiscovered); + MarkSourcesWithStatus(verifiedSources, DiscoveryStatus.NotDiscovered, _sourcesWithDiscoveryStatus); } } @@ -161,9 +161,9 @@ public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEve var discoveryCompleteEventsArgs = new DiscoveryCompleteEventArgs( totalDiscoveredTestCount, _cancellationTokenSource.IsCancellationRequested, - GetFilteredSources(DiscoveryStatus.FullyDiscovered), - GetFilteredSources(DiscoveryStatus.PartiallyDiscovered), - GetFilteredSources(DiscoveryStatus.NotDiscovered)); + GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered, _sourcesWithDiscoveryStatus), + GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered, _sourcesWithDiscoveryStatus), + GetSourcesWithStatus(DiscoveryStatus.NotDiscovered, _sourcesWithDiscoveryStatus)); discoveryCompleteEventsArgs.Metrics = _requestData.MetricsCollection.Metrics; @@ -199,14 +199,14 @@ public void Abort(ITestDiscoveryEventsHandler2 eventHandler) var discoveryCompleteEventArgs = new DiscoveryCompleteEventArgs( -1, true, - GetFilteredSources(DiscoveryStatus.FullyDiscovered), - GetFilteredSources(DiscoveryStatus.PartiallyDiscovered), - GetFilteredSources(DiscoveryStatus.NotDiscovered)); + GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered, _sourcesWithDiscoveryStatus), + GetSourcesWithStatus(DiscoveryStatus.PartiallyDiscovered, _sourcesWithDiscoveryStatus), + GetSourcesWithStatus(DiscoveryStatus.NotDiscovered, _sourcesWithDiscoveryStatus)); eventHandler.HandleDiscoveryComplete(discoveryCompleteEventArgs, null); } - private void OnReportTestCases(IEnumerable testCases) + private void OnReportTestCases(ICollection testCases) { UpdateTestCases(testCases, _discoveryCriteria.Package); @@ -327,9 +327,9 @@ private static void UpdateTestCases(IEnumerable testCases, string pack /// Mark sources based on already discovered testCases /// /// List of testCases which were already discovered - private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCases) + private void MarkSourcesBasedOnDiscoveredTestCases(ICollection testCases) { - if (testCases is null || !testCases.Any()) + if (testCases is null) { return; } @@ -362,16 +362,13 @@ private void MarkSourcesBasedOnDiscoveredTestCases(IEnumerable testCas /// Last chunk of testCases which were discovered private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) { - var lastChunkSources = lastChunk.Select(testcase => testcase.Source); - // When all testcases in project is dividable by 10 then lastChunk is coming as empty - // So we need to take the lastSource and mark it as FullyDiscovered - if (!lastChunk.Any()) - { - lastChunkSources = new List() { _previousSource }; - } + // So we need to take the lastSource and mark it as FullyDiscovered. + var lastChunkSources = lastChunk.Count > 0 + ? lastChunk.Select(testcase => testcase.Source).ToList() + : new List() { _previousSource }; - MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered); + MarkSourcesWithStatus(lastChunkSources, DiscoveryStatus.FullyDiscovered, _sourcesWithDiscoveryStatus); } /// @@ -380,16 +377,17 @@ private void MarkTheLastChunkSourcesAsFullyDiscovered(IList lastChunk) /// Sources to mark /// DiscoveryStatus to mark for source private void MarkSourceWithStatus(string source, DiscoveryStatus status) - => MarkSourcesWithStatus(new[] { source }, status); + => MarkSourcesWithStatus(new[] { source }, status, _sourcesWithDiscoveryStatus); /// /// Mark sources with particular DiscoveryStatus /// /// List of sources to mark /// DiscoveryStatus to mark for list of sources - private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus status) + internal static void MarkSourcesWithStatus(ICollection sources, DiscoveryStatus status, + ConcurrentDictionary sourcesWithDiscoveryStatus) { - if (sources is null || !sources.Any()) + if (sources is null) { return; } @@ -401,29 +399,36 @@ private void MarkSourcesWithStatus(IEnumerable sources, DiscoveryStatus continue; } - if (status != DiscoveryStatus.NotDiscovered && !_sourcesWithDiscoveryStatus.ContainsKey(source)) - { - EqtTrace.Warning($"DiscoveryManager.MarkSourcesWithStatus: SourcesWithDiscoveryStatus does not contain {source}."); - } - else - { - _sourcesWithDiscoveryStatus[source] = status; - EqtTrace.Info($"DiscoveryManager.MarkSourcesWithStatus: Marking {source} with {status} status."); - } + sourcesWithDiscoveryStatus.AddOrUpdate(source, + _ => + { + if (status != DiscoveryStatus.NotDiscovered) + { + EqtTrace.Warning($"Undiscovered {source}."); + } + + return status; + }, + (_, _) => + { + EqtTrace.Info($"Marking {source} with {status} status."); + return status; + }); } } /// - /// Filter discovery sources based on discovery status condition + /// Returns sources with particular discovery status. /// - /// discoveryStatus indicates if source was fully/partially/not discovered + /// Status to filter /// - private List GetFilteredSources(DiscoveryStatus discoveryStatus) + internal static List GetSourcesWithStatus(DiscoveryStatus discoveryStatus, + ConcurrentDictionary sourcesWithDiscoveryStatus) { // If by some accident SourcesWithDiscoveryStatus map is empty we will return empty list - return _sourcesWithDiscoveryStatus is null || _sourcesWithDiscoveryStatus.IsEmpty + return sourcesWithDiscoveryStatus is null || sourcesWithDiscoveryStatus.IsEmpty ? new List() - : _sourcesWithDiscoveryStatus + : sourcesWithDiscoveryStatus .Where(source => source.Value == discoveryStatus) .Select(source => source.Key) .ToList(); diff --git a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs index d3c171eebb..b13d803199 100644 --- a/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs +++ b/test/Microsoft.TestPlatform.CrossPlatEngine.UnitTests/Client/Parallel/ParallelDiscoveryDataAggregatorTests.cs @@ -261,14 +261,14 @@ public void AggregateShouldAggregateSourcesCorrectly() var sources = new List() { "sample.dll" }; // Act - aggregator.AggregateTheSourcesWithDiscoveryStatus(sources, DiscoveryStatus.NotDiscovered); + aggregator.MarkSourcesWithStatus(sources, DiscoveryStatus.NotDiscovered); var sourcesWithNotDiscoveredStatus = aggregator.GetSourcesWithStatus(DiscoveryStatus.NotDiscovered); // Assert Assert.AreEqual(1, sourcesWithNotDiscoveredStatus.Count); // Act - aggregator.AggregateTheSourcesWithDiscoveryStatus(sources, DiscoveryStatus.FullyDiscovered); + aggregator.MarkSourcesWithStatus(sources, DiscoveryStatus.FullyDiscovered); var sourcesWithFullyDiscoveryStatus = aggregator.GetSourcesWithStatus(DiscoveryStatus.FullyDiscovered); // Assert From d29f00715449570df68ffd5819772717794541ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 16 Feb 2022 15:23:18 +0100 Subject: [PATCH 29/31] Make public as class is internal --- .../Client/Parallel/ParallelDiscoveryDataAggregator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs index af8b4ca3c1..bd257cb56e 100644 --- a/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs +++ b/src/Microsoft.TestPlatform.CrossPlatEngine/Client/Parallel/ParallelDiscoveryDataAggregator.cs @@ -138,14 +138,14 @@ public void AggregateDiscoveryDataMetrics(IDictionary metrics) /// Aggregate the source as fully discovered /// /// Fully discovered source - internal void MarkSourcesWithStatus(ICollection sources, DiscoveryStatus status) + public void MarkSourcesWithStatus(ICollection sources, DiscoveryStatus status) => DiscoveryManager.MarkSourcesWithStatus(sources, status, _sourcesWithDiscoveryStatus); /// /// Aggregates the value indicating if we already sent message to IDE. /// /// Boolean value if we already sent message to IDE - internal void AggregateIsMessageSent(bool isMessageSent) + public void AggregateIsMessageSent(bool isMessageSent) { IsMessageSent = IsMessageSent || isMessageSent; } @@ -155,6 +155,6 @@ internal void AggregateIsMessageSent(bool isMessageSent) /// /// Status to filter /// - internal List GetSourcesWithStatus(DiscoveryStatus status) + public List GetSourcesWithStatus(DiscoveryStatus status) => DiscoveryManager.GetSourcesWithStatus(status, _sourcesWithDiscoveryStatus); } From 47ff337038602df1920d061e29ebbda4c700ae5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 16 Feb 2022 15:35:57 +0100 Subject: [PATCH 30/31] Fix naming --- .../Discovery/DiscoveryRequest.cs | 4 ++-- .../Discovery/DiscoveryRequestTests.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index ee72fb3da4..20c0622d01 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -26,7 +26,7 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery; public sealed class DiscoveryRequest : IDiscoveryRequest, ITestDiscoveryEventsHandler2 { private readonly IDataSerializer _dataSerializer; - internal /* for testing purposes */ readonly ProtocolConfig _protocolConfig = Constants.DefaultProtocolConfig; + internal /* for testing purposes */ readonly ProtocolConfig ProtocolConfig = Constants.DefaultProtocolConfig; /// /// Initializes a new instance of the class. @@ -120,7 +120,7 @@ public void Abort() { // If testhost has old version, we should use old cancel logic // to be consistent and not create regression issues - if (_protocolConfig.Version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) + if (ProtocolConfig.Version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) { DiscoveryManager.Abort(); } diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs index 94a72953de..5cb1b4b12c 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs @@ -104,7 +104,7 @@ public void AbortIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbort(int vers _discoveryRequest.DiscoverAsync(); // Set the protocol version to a version not supporting new abort overload. - _discoveryRequest._protocolConfig.Version = version; + _discoveryRequest.ProtocolConfig.Version = version; _discoveryRequest.Abort(); _discoveryManager.Verify(dm => dm.Abort(), Times.Once); From 1f496bde9fab0a4829f345e0fb0fe30a51d0af08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 17 Feb 2022 14:03:24 +0100 Subject: [PATCH 31/31] Improves tests and remove un-needed field --- .../Discovery/DiscoveryRequest.cs | 3 +- .../Discovery/DiscoveryRequestTests.cs | 34 +++++++++---------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs index 20c0622d01..5f3b16e855 100644 --- a/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs +++ b/src/Microsoft.TestPlatform.Client/Discovery/DiscoveryRequest.cs @@ -26,7 +26,6 @@ namespace Microsoft.VisualStudio.TestPlatform.Client.Discovery; public sealed class DiscoveryRequest : IDiscoveryRequest, ITestDiscoveryEventsHandler2 { private readonly IDataSerializer _dataSerializer; - internal /* for testing purposes */ readonly ProtocolConfig ProtocolConfig = Constants.DefaultProtocolConfig; /// /// Initializes a new instance of the class. @@ -120,7 +119,7 @@ public void Abort() { // If testhost has old version, we should use old cancel logic // to be consistent and not create regression issues - if (ProtocolConfig.Version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) + if (Constants.DefaultProtocolConfig.Version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) { DiscoveryManager.Abort(); } diff --git a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs index 5cb1b4b12c..24a21be30c 100644 --- a/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs +++ b/test/Microsoft.TestPlatform.Client.UnitTests/Discovery/DiscoveryRequestTests.cs @@ -44,6 +44,10 @@ public DiscoveryRequestTests() _discoveryRequest = new DiscoveryRequest(_mockRequestData.Object, _discoveryCriteria, _discoveryManager.Object, _loggerManager.Object, _mockDataSerializer.Object); } + public static IEnumerable ProtocolConfigVersionProvider + => Enumerable.Range(0, Constants.DefaultProtocolConfig.Version + 1) + .Select(x => new object[] { x }); + [TestMethod] public void ConstructorSetsDiscoveryCriteriaAndDiscoveryManager() { @@ -92,32 +96,26 @@ public void AbortIfDiscoveryRequestDisposedShouldThrowObjectDisposedException() } [DataTestMethod] - [DataRow(0)] - [DataRow(1)] - [DataRow(2)] - [DataRow(3)] - [DataRow(4)] - [DataRow(5)] + [DynamicData(nameof(ProtocolConfigVersionProvider))] public void AbortIfDiscoveryIsinProgressShouldCallDiscoveryManagerAbort(int version) { // Just to set the IsDiscoveryInProgress flag _discoveryRequest.DiscoverAsync(); - // Set the protocol version to a version not supporting new abort overload. - _discoveryRequest.ProtocolConfig.Version = version; + Constants.DefaultProtocolConfig.Version = version; _discoveryRequest.Abort(); - _discoveryManager.Verify(dm => dm.Abort(), Times.Once); - } - [TestMethod] - public void AbortIfDiscoveryIsinProgressShouldAndSufficientProtocolVersionCallsDiscoveryManagerAbortThis() - { - // Just to set the IsDiscoveryInProgress flag - _discoveryRequest.DiscoverAsync(); - - _discoveryRequest.Abort(); - _discoveryManager.Verify(dm => dm.Abort(_discoveryRequest), Times.Once); + if (version < Constants.MinimumProtocolVersionWithCancelDiscoveryEventHandlerSupport) + { + _discoveryManager.Verify(dm => dm.Abort(), Times.Once); + _discoveryManager.Verify(dm => dm.Abort(_discoveryRequest), Times.Never); + } + else + { + _discoveryManager.Verify(dm => dm.Abort(), Times.Never); + _discoveryManager.Verify(dm => dm.Abort(_discoveryRequest), Times.Once); + } } [TestMethod]