/// <summary> /// Discovers tests /// </summary> /// <param name="discoveryCriteria">Settings, parameters for the discovery request</param> /// <param name="eventHandler">EventHandler for handling discovery events from Engine</param> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler eventHandler) { try { if (!this.testHostManager.Shared) { // If the test host doesn't support sharing across sources, we must initialize it // with sources. this.InitializeExtensions(discoveryCriteria.Sources); } this.SetupChannel(discoveryCriteria.Sources); this.RequestSender.DiscoverTests(discoveryCriteria, eventHandler); } catch (Exception exception) { EqtTrace.Error("ProxyDiscoveryManager.DiscoverTests: Failed to discover tests: {0}", exception); // Log to vs ide test output var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = exception.Message }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload); eventHandler.HandleRawMessage(rawMessage); // Log to vstest.console eventHandler.HandleLogMessage(TestMessageLevel.Error, exception.Message); eventHandler.HandleDiscoveryComplete(0, new List <ObjectModel.TestCase>(), false); } }
private void OnDiscoveryAbort(ITestDiscoveryEventsHandler eventHandler, Exception exception, bool getClientError) { if (this.IsOperationComplete()) { EqtTrace.Verbose("TestRequestSender: OnDiscoveryAbort: Operation is already complete. Skip error message."); return; } EqtTrace.Verbose("TestRequestSender: OnDiscoveryAbort: Set operation complete."); this.SetOperationComplete(); var reason = this.GetAbortErrorMessage(exception, getClientError); EqtTrace.Error("TestRequestSender: Aborting test discovery because {0}", reason); this.LogErrorMessage(string.Format(CommonResources.AbortedTestDiscovery, reason)); // Notify discovery abort to IDE test output var payload = new DiscoveryCompletePayload() { IsAborted = true, LastDiscoveredTests = null, TotalTests = -1 }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.DiscoveryComplete, payload); eventHandler.HandleRawMessage(rawMessage); // Complete discovery eventHandler.HandleDiscoveryComplete(-1, null, true); }
private void OnDiscoveryAbort(ITestDiscoveryEventsHandler eventHandler) { // Log to vstest console eventHandler.HandleLogMessage(TestMessageLevel.Error, CommonResources.AbortedTestDiscovery); // Log to vs ide test output var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = CommonResources.AbortedTestDiscovery }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload); eventHandler.HandleRawMessage(rawMessage); // Notify discovery abort to IDE test output var payload = new DiscoveryCompletePayload() { IsAborted = true, LastDiscoveredTests = null, TotalTests = -1 }; rawMessage = this.dataSerializer.SerializePayload(MessageType.DiscoveryComplete, payload); eventHandler.HandleRawMessage(rawMessage); // Complete discovery eventHandler.HandleDiscoveryComplete(-1, null, true); this.CleanupCommunicationIfProcessExit(); }
private void OnDiscoveryAbort(ITestDiscoveryEventsHandler eventHandler, Exception exception) { EqtTrace.Error("Server: TestExecution: Aborting test discovery because {0}", exception); var reason = string.Format(CommonResources.AbortedTestDiscovery, exception?.Message); // Log to vstest console eventHandler.HandleLogMessage(TestMessageLevel.Error, reason); // Log to vs ide test output var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = reason }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload); eventHandler.HandleRawMessage(rawMessage); // Notify discovery abort to IDE test output var payload = new DiscoveryCompletePayload() { IsAborted = true, LastDiscoveredTests = null, TotalTests = -1 }; rawMessage = this.dataSerializer.SerializePayload(MessageType.DiscoveryComplete, payload); eventHandler.HandleRawMessage(rawMessage); // Complete discovery eventHandler.HandleDiscoveryComplete(-1, null, true); this.CleanupCommunicationIfProcessExit(); }
public ParallelDiscoveryEventsHandler(IProxyDiscoveryManager proxyDiscoveryManager, ITestDiscoveryEventsHandler actualDiscoveryEventsHandler, IParallelProxyDiscoveryManager parallelProxyDiscoveryManager, ParallelDiscoveryDataAggregator discoveryDataAggregator) : this(proxyDiscoveryManager, actualDiscoveryEventsHandler, parallelProxyDiscoveryManager, discoveryDataAggregator, JsonDataSerializer.Instance) { }
/// <summary> /// Discovers tests /// </summary> /// <param name="discoveryCriteria">Settings, parameters for the discovery request</param> /// <param name="eventHandler">EventHandler for handling discovery events from Engine</param> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler eventHandler) { try { this.isCommunicationEstablished = this.SetupChannel(discoveryCriteria.Sources, this.cancellationTokenSource.Token); if (this.isCommunicationEstablished) { this.InitializeExtensions(discoveryCriteria.Sources); this.RequestSender.DiscoverTests(discoveryCriteria, eventHandler); } } catch (Exception exception) { EqtTrace.Error("ProxyDiscoveryManager.DiscoverTests: Failed to discover tests: {0}", exception); // Log to vs ide test output var testMessagePayload = new TestMessagePayload { MessageLevel = TestMessageLevel.Error, Message = exception.Message }; var rawMessage = this.dataSerializer.SerializePayload(MessageType.TestMessage, testMessagePayload); eventHandler.HandleRawMessage(rawMessage); // Log to vstest.console // Send a discovery complete to caller. Similar logic is also used in ParallelProxyDiscoveryManager.DiscoverTestsOnConcurrentManager // Aborted is `true`: in case of parallel discovery (or non shared host), an aborted message ensures another discovery manager // created to replace the current one. This will help if the current discovery manager is aborted due to irreparable error // and the test host is lost as well. eventHandler.HandleLogMessage(TestMessageLevel.Error, exception.Message); eventHandler.HandleDiscoveryComplete(-1, new List <ObjectModel.TestCase>(), true); } }
/// <summary> /// Discovers tests /// </summary> /// <param name="discoveryCriteria">Settings, parameters for the discovery request</param> /// <param name="eventHandler">EventHandler for handling discovery events from Engine</param> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler eventHandler) { var discoveryResultCache = new DiscoveryResultCache( discoveryCriteria.FrequencyOfDiscoveredTestsEvent, discoveryCriteria.DiscoveredTestEventTimeout, this.OnReportTestCases); try { EqtTrace.Info("TestDiscoveryManager.DoDiscovery: Background test discovery started."); this.testDiscoveryEventsHandler = eventHandler; var verifiedExtensionSourceMap = new Dictionary <string, IEnumerable <string> >(); // Validate the sources foreach (var kvp in discoveryCriteria.AdapterSourceMap) { var verifiedSources = GetValidSources(kvp.Value, this.sessionMessageLogger); if (verifiedSources.Any()) { verifiedExtensionSourceMap.Add(kvp.Key, kvp.Value); } } // If there are sources to discover if (verifiedExtensionSourceMap.Any()) { new DiscovererEnumerator(discoveryResultCache).LoadTests( verifiedExtensionSourceMap, RunSettingsUtilities.CreateAndInitializeRunSettings(discoveryCriteria.RunSettings), this.sessionMessageLogger); } } finally { // Discovery complete. Raise the DiscoveryCompleteEvent. EqtTrace.Verbose("TestDiscoveryManager.DoDiscovery: Background Test Discovery complete."); var totalDiscoveredTestCount = discoveryResultCache.TotalDiscoveredTests; var lastChunk = discoveryResultCache.Tests; EqtTrace.Verbose("TestDiscoveryManager.DiscoveryComplete: Calling DiscoveryComplete callback."); if (eventHandler != null) { eventHandler.HandleDiscoveryComplete(totalDiscoveredTestCount, lastChunk, false); } else { EqtTrace.Warning( "DiscoveryManager: Could not pass the discovery complete message as the callback is null."); } EqtTrace.Verbose("TestDiscoveryManager.DiscoveryComplete: Called DiscoveryComplete callback."); this.testDiscoveryEventsHandler = null; } }
/// <inheritdoc/> public void DiscoverTests( IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) { this.DiscoverTests( sources, discoverySettings, options: null, discoveryEventsHandler: new DiscoveryEventsHandleConverter(discoveryEventsHandler)); }
/// <inheritdoc/> public async Task DiscoverTestsAsync( IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) { await this.DiscoverTestsAsync( sources, discoverySettings, options : null, discoveryEventsHandler : new DiscoveryEventsHandleConverter(discoveryEventsHandler)); }
internal ParallelDiscoveryEventsHandler(IProxyDiscoveryManager proxyDiscoveryManager, ITestDiscoveryEventsHandler actualDiscoveryEventsHandler, IParallelProxyDiscoveryManager parallelProxyDiscoveryManager, ParallelDiscoveryDataAggregator discoveryDataAggregator, IDataSerializer dataSerializer) { this.proxyDiscoveryManager = proxyDiscoveryManager; this.actualDiscoveryEventsHandler = actualDiscoveryEventsHandler; this.parallelProxyDiscoveryManager = parallelProxyDiscoveryManager; this.discoveryDataAggregator = discoveryDataAggregator; this.dataSerializer = dataSerializer; }
/// <inheritdoc/> public bool HandlePartialDiscoveryComplete(IProxyDiscoveryManager proxyDiscoveryManager, long totalTests, IEnumerable <TestCase> lastChunk, bool isAborted) { var allDiscoverersCompleted = false; if (!this.SharedHosts) { this.concurrentManagerHandlerMap.Remove(proxyDiscoveryManager); proxyDiscoveryManager.Close(); proxyDiscoveryManager = this.CreateNewConcurrentManager(); var parallelEventsHandler = new ParallelDiscoveryEventsHandler( proxyDiscoveryManager, this.currentDiscoveryEventsHandler, this, this.currentDiscoveryDataAggregator); this.concurrentManagerHandlerMap.Add(proxyDiscoveryManager, parallelEventsHandler); } // In Case of Cancel or Abort, no need to trigger discovery for rest of the data // If there are no more sources/testcases, a parallel executor is truly done with discovery if (isAborted || !this.DiscoverTestsOnConcurrentManager(proxyDiscoveryManager)) { lock (this.discoveryStatusLockObject) { // Each concurrent Executor calls this method // So, we need to keep track of total discoverycomplete calls this.discoveryCompletedClients++; allDiscoverersCompleted = this.discoveryCompletedClients == this.concurrentManagerInstances.Length; } // verify that all executors are done with the discovery and there are no more sources/testcases to execute if (allDiscoverersCompleted) { // Reset enumerators this.sourceEnumerator = null; this.currentDiscoveryDataAggregator = null; this.currentDiscoveryEventsHandler = null; // Dispose concurrent executors // Do not do the cleanuptask in the current thread as we will unncessarily add to discovery time this.lastParallelDiscoveryCleanUpTask = Task.Run(() => { this.UpdateParallelLevel(0); }); } } return(allDiscoverersCompleted); }
/// <inheritdoc/> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler discoveryEventsHandler) { try { this.communicationManager.SendMessage(MessageType.StartDiscovery, discoveryCriteria, version: this.protocolVersion); var isDiscoveryComplete = false; // Cycle through the messages that the testhost sends. // Currently each of the operations are not separate tasks since they should not each take much time. This is just a notification. while (!isDiscoveryComplete) { var rawMessage = this.TryReceiveRawMessage(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("Received message: {0}", rawMessage); } // Send raw message first to unblock handlers waiting to send message to IDEs discoveryEventsHandler.HandleRawMessage(rawMessage); var message = this.dataSerializer.DeserializeMessage(rawMessage); if (string.Equals(MessageType.TestCasesFound, message.MessageType)) { var testCases = this.dataSerializer.DeserializePayload <IEnumerable <TestCase> >(message); discoveryEventsHandler.HandleDiscoveredTests(testCases); } else if (string.Equals(MessageType.DiscoveryComplete, message.MessageType)) { var discoveryCompletePayload = this.dataSerializer.DeserializePayload <DiscoveryCompletePayload>(message); discoveryEventsHandler.HandleDiscoveryComplete( discoveryCompletePayload.TotalTests, discoveryCompletePayload.LastDiscoveredTests, discoveryCompletePayload.IsAborted); isDiscoveryComplete = true; } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { var testMessagePayload = this.dataSerializer.DeserializePayload <TestMessagePayload>(message); discoveryEventsHandler.HandleLogMessage( testMessagePayload.MessageLevel, testMessagePayload.Message); } } } catch (Exception ex) { this.OnDiscoveryAbort(discoveryEventsHandler, ex); } }
private void DiscoverTestsPrivate(ITestDiscoveryEventsHandler discoveryEventsHandler) { this.currentDiscoveryEventsHandler = discoveryEventsHandler; // Cleanup Task for cleaning up the parallel executors except for the default one // We do not do this in Sync so that this task does not add up to discovery time if (this.lastParallelDiscoveryCleanUpTask != null) { try { this.lastParallelDiscoveryCleanUpTask.Wait(); } catch (Exception ex) { // if there is an exception disposing off concurrent hosts ignore it if (EqtTrace.IsWarningEnabled) { EqtTrace.Warning("ParallelProxyDiscoveryManager: Exception while invoking an action on DiscoveryManager: {0}", ex); } } this.lastParallelDiscoveryCleanUpTask = null; } // Reset the discoverycomplete data this.discoveryCompletedClients = 0; // One data aggregator per parallel discovery this.currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator(); this.concurrentManagerHandlerMap = new Dictionary <IProxyDiscoveryManager, ITestDiscoveryEventsHandler>(); for (int i = 0; i < this.concurrentManagerInstances.Length; i++) { var concurrentManager = this.concurrentManagerInstances[i]; var parallelEventsHandler = new ParallelDiscoveryEventsHandler( concurrentManager, discoveryEventsHandler, this, this.currentDiscoveryDataAggregator); this.concurrentManagerHandlerMap.Add(concurrentManager, parallelEventsHandler); Task.Run(() => this.DiscoverTestsOnConcurrentManager(concurrentManager)); } }
/// <summary> /// Discovers tests /// </summary> /// <param name="discoveryCriteria">Settings, parameters for the discovery request</param> /// <param name="eventHandler">EventHandler for handling discovery events from Engine</param> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler eventHandler) { try { if (!this.testHostManager.Shared) { // If the test host doesn't support sharing across sources, we must initialize it // with sources. this.InitializeExtensions(discoveryCriteria.Sources); } this.SetupChannel(discoveryCriteria.Sources); this.RequestSender.DiscoverTests(discoveryCriteria, eventHandler); } catch (Exception exception) { eventHandler.HandleLogMessage(TestMessageLevel.Error, exception.Message); eventHandler.HandleDiscoveryComplete(0, new List <ObjectModel.TestCase>(), false); } }
private async Task SendMessageAndListenAndReportTestCasesAsync(IEnumerable <string> sources, string runSettings, ITestDiscoveryEventsHandler eventHandler) { try { this.communicationManager.SendMessage( MessageType.StartDiscovery, new DiscoveryRequestPayload() { Sources = sources, RunSettings = runSettings }, this.protocolVersion); var isDiscoveryComplete = false; // Cycle through the messages that the vstest.console sends. // Currently each of the operations are not separate tasks since they should not each take much time. // This is just a notification. while (!isDiscoveryComplete) { var message = await this.TryReceiveMessageAsync(); if (string.Equals(MessageType.TestCasesFound, message.MessageType)) { var testCases = this.dataSerializer.DeserializePayload <IEnumerable <TestCase> >(message); eventHandler.HandleDiscoveredTests(testCases); } else if (string.Equals(MessageType.DiscoveryComplete, message.MessageType)) { var discoveryCompletePayload = this.dataSerializer.DeserializePayload <DiscoveryCompletePayload>(message); eventHandler.HandleDiscoveryComplete( discoveryCompletePayload.TotalTests, discoveryCompletePayload.LastDiscoveredTests, discoveryCompletePayload.IsAborted); isDiscoveryComplete = true; } else if (string.Equals(MessageType.TestMessage, message.MessageType)) { var testMessagePayload = this.dataSerializer.DeserializePayload <TestMessagePayload>(message); eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message); } } } catch (Exception exception) { EqtTrace.Error("Aborting Test Discovery Operation: {0}", exception); eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestsDiscovery); eventHandler.HandleDiscoveryComplete(-1, null, true); CleanupCommunicationIfProcessExit(); } this.testPlatformEventSource.TranslationLayerDiscoveryStop(); }
/// <summary> /// Asynchronous equivalent of <see cref="DiscoverTests(IEnumerable{string}, string, ITestDiscoveryEventsHandler)"/>. /// </summary> public async Task DiscoverTestsAsync(IEnumerable <string> sources, string runSettings, ITestDiscoveryEventsHandler eventHandler) { await this.SendMessageAndListenAndReportTestCasesAsync(sources, runSettings, eventHandler); }
/// <inheritdoc/> public void DiscoverTests(IEnumerable <string> sources, string runSettings, ITestDiscoveryEventsHandler eventHandler) { this.SendMessageAndListenAndReportTestCases(sources, runSettings, eventHandler); }
// simulate the discovery of tests private static void DiscoverTests(IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler, ICollection <TestCase> tests, bool aborted) { Task.Run(() => discoveryEventsHandler.HandleDiscoveredTests(tests)). ContinueWith((t, u) => discoveryEventsHandler.HandleDiscoveryComplete((int)u, null, aborted), tests.Count); }
/// <inheritdoc/> public void DiscoverTests(IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) { this.testPlatformEventSource.TranslationLayerDiscoveryStart(); this.EnsureInitialized(); // Converts ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 var discoveryCompleteEventsHandler2 = new DiscoveryEventsHandleConverter(discoveryEventsHandler); this.requestSender.DiscoverTests(sources, discoverySettings, options: null, discoveryEventsHandler: discoveryCompleteEventsHandler2); }
/// <inheritdoc/> public void DiscoverTests(IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) { this.testPlatformEventSource.TranslationLayerDiscoveryStart(); this.EnsureInitialized(); this.requestSender.DiscoverTests(sources, discoverySettings, discoveryEventsHandler); }
/// <summary> /// The Discovery Complete Handler. /// Converts the ITestDiscoveryEventsHandler to ITestDiscoveryEventsHandler2 /// </summary> /// <param name="testDiscoveryEventsHandler"></param> public DiscoveryEventsHandleConverter(ITestDiscoveryEventsHandler testDiscoveryEventsHandler) { this.testDiscoveryEventsHandler = testDiscoveryEventsHandler ?? throw new ArgumentNullException(nameof(testDiscoveryEventsHandler)); }
public void DiscoverTests(IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) => inner.DiscoverTests(sources, discoverySettings, discoveryEventsHandler);
/// <inheritdoc /> public void DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler discoveryEventsHandler) { this.messageEventHandler = discoveryEventsHandler; this.onDisconnected = (disconnectedEventArgs) => { this.OnDiscoveryAbort(discoveryEventsHandler, disconnectedEventArgs.Error, true); }; this.onMessageReceived = (sender, args) => { try { var rawMessage = args.Data; // Currently each of the operations are not separate tasks since they should not each take much time. This is just a notification. if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("TestRequestSender: Received message: {0}", rawMessage); } // Send raw message first to unblock handlers waiting to send message to IDEs discoveryEventsHandler.HandleRawMessage(rawMessage); var data = this.dataSerializer.DeserializeMessage(rawMessage); switch (data.MessageType) { case MessageType.TestCasesFound: var testCases = this.dataSerializer.DeserializePayload <IEnumerable <TestCase> >(data); discoveryEventsHandler.HandleDiscoveredTests(testCases); break; case MessageType.DiscoveryComplete: var discoveryCompletePayload = this.dataSerializer.DeserializePayload <DiscoveryCompletePayload>(data); discoveryEventsHandler.HandleDiscoveryComplete( discoveryCompletePayload.TotalTests, discoveryCompletePayload.LastDiscoveredTests, discoveryCompletePayload.IsAborted); this.SetOperationComplete(); break; case MessageType.TestMessage: var testMessagePayload = this.dataSerializer.DeserializePayload <TestMessagePayload>( data); discoveryEventsHandler.HandleLogMessage( testMessagePayload.MessageLevel, testMessagePayload.Message); break; } } catch (Exception ex) { this.OnDiscoveryAbort(discoveryEventsHandler, ex, false); } }; this.channel.MessageReceived += this.onMessageReceived; var message = this.dataSerializer.SerializePayload( MessageType.StartDiscovery, discoveryCriteria, this.protocolVersion); this.channel.Send(message); }
/// <inheritdoc/> void IProxyDiscoveryManager.DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler eventHandler) { this.actualDiscoveryCriteria = discoveryCriteria; // Set the enumerator for parallel yielding of sources // Whenever a concurrent executor becomes free, it picks up the next source using this enumerator this.sourceEnumerator = discoveryCriteria.Sources.GetEnumerator(); this.DiscoverTestsPrivate(eventHandler); }
/// <inheritdoc/> public void DiscoverTests(IEnumerable <string> sources, string discoverySettings, ITestDiscoveryEventsHandler discoveryEventsHandler) { this.EnsureInitialized(); this.requestSender.DiscoverTests(sources, discoverySettings, discoveryEventsHandler); }