Example #1
0
        private async Task SendMessageAndListenAndReportAttachmentsProcessingResultAsync(IEnumerable <AttachmentSet> attachments, bool collectMetrics, ITestRunAttachmentsProcessingEventsHandler eventHandler, CancellationToken cancellationToken)
        {
            try
            {
                var payload = new TestRunAttachmentsProcessingPayload
                {
                    Attachments    = attachments,
                    CollectMetrics = collectMetrics
                };

                this.communicationManager.SendMessage(MessageType.TestRunAttachmentsProcessingStart, payload);
                var isTestRunAttachmentsProcessingComplete = false;

                using (cancellationToken.Register(() => this.communicationManager.SendMessage(MessageType.TestRunAttachmentsProcessingCancel)))
                {
                    // 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 (!isTestRunAttachmentsProcessingComplete)
                    {
                        var message = await this.TryReceiveMessageAsync().ConfigureAwait(false);

                        if (string.Equals(MessageType.TestRunAttachmentsProcessingComplete, message.MessageType))
                        {
                            if (EqtTrace.IsInfoEnabled)
                            {
                                EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Process complete.");
                            }

                            var testRunAttachmentsProcessingCompletePayload = this.dataSerializer.DeserializePayload <TestRunAttachmentsProcessingCompletePayload>(message);

                            eventHandler.HandleTestRunAttachmentsProcessingComplete(testRunAttachmentsProcessingCompletePayload.AttachmentsProcessingCompleteEventArgs, testRunAttachmentsProcessingCompletePayload.Attachments);
                            isTestRunAttachmentsProcessingComplete = true;
                        }
                        else if (string.Equals(MessageType.TestRunAttachmentsProcessingProgress, message.MessageType))
                        {
                            var testRunAttachmentsProcessingProgressPayload = this.dataSerializer.DeserializePayload <TestRunAttachmentsProcessingProgressPayload>(message);
                            eventHandler.HandleTestRunAttachmentsProcessingProgress(testRunAttachmentsProcessingProgressPayload.AttachmentsProcessingProgressEventArgs);
                        }
                        else if (string.Equals(MessageType.TestMessage, message.MessageType))
                        {
                            var testMessagePayload = this.dataSerializer.DeserializePayload <TestMessagePayload>(message);
                            eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message);
                        }
                        else
                        {
                            EqtTrace.Warning($"VsTestConsoleRequestSender.SendMessageAndListenAndReportAttachments: Unexpected message received {message.MessageType}.");
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                EqtTrace.Error("Aborting Test Session End Operation: {0}", exception);
                eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestRunAttachmentsProcessing);
                eventHandler.HandleTestRunAttachmentsProcessingComplete(new TestRunAttachmentsProcessingCompleteEventArgs(false, exception), null);

                // Earlier we were closing the connection with vstest.console in case of exceptions
                // Removing that code because vstest.console might be in a healthy state and letting the client
                // know of the error, so that the TL can wait for the next instruction from the client itself.
                // Also, connection termination might not kill the process which could result in files being locked by testhost.
            }
            finally
            {
                this.testPlatformEventSource.TranslationLayerTestRunAttachmentsProcessingStop();
            }
        }
Example #2
0
        public void OnMessageReceived(object sender, MessageReceivedEventArgs messageReceivedArgs)
        {
            var message = this.dataSerializer.DeserializeMessage(messageReceivedArgs.Data);

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("TestRequestHandler.ProcessRequests: received message: {0}", message);
            }

            switch (message.MessageType)
            {
            case MessageType.VersionCheck:
                var version = this.dataSerializer.DeserializePayload <int>(message);
                // choose the highest version that we both support
                var negotiatedVersion = Math.Min(version, highestSupportedVersion);
                // BUT don't choose 3, because protocol version 3 has performance problems in 16.7.1-16.8. Those problems are caused
                // by choosing payloadSerializer instead of payloadSerializer2 for protocol version 3.
                //
                // We cannot just update the code to choose the new serializer, because then that change would apply only to testhost.
                // Testhost is is delivered by Microsoft.NET.Test.SDK nuget package, and can be used with an older vstest.console.
                // An older vstest.console, that supports protocol version 3, would serialize its messages using payloadSerializer,
                // but the fixed testhost would serialize it using payloadSerializer2, resulting in incompatible messages.
                //
                // Instead we must downgrade to protocol version 2 when 3 would be negotiated. Or higher when higher version
                // would be negotiated.
                if (negotiatedVersion != 3)
                {
                    this.protocolVersion = negotiatedVersion;
                }
                else
                {
                    var flag               = Environment.GetEnvironmentVariable("VSTEST_DISABLE_PROTOCOL_3_VERSION_DOWNGRADE");
                    var flagIsEnabled      = flag != null && flag != "0";
                    var dowgradeIsDisabled = flagIsEnabled;
                    if (dowgradeIsDisabled)
                    {
                        this.protocolVersion = negotiatedVersion;
                    }
                    else
                    {
                        this.protocolVersion = 2;
                    }
                }

                // Send the negotiated protocol to request sender
                this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion));

                // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized
                if (!string.IsNullOrEmpty(EqtTrace.LogFile))
                {
                    this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile));
                }
                else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
                {
                    this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization);
                }
                break;

            case MessageType.DiscoveryInitialize:
            {
                EqtTrace.Info("Discovery Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler     = new TestDiscoveryEventHandler(this);
                var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions, discoveryEventsHandler), 0);
                break;
            }

            case MessageType.StartDiscovery:
            {
                //System.Diagnostics.Debugger.Launch();
                //System.Diagnostics.Debugger.Break();

                EqtTrace.Info("Discovery started.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler = new TestDiscoveryEventHandler(this);
                var discoveryCriteria      = this.dataSerializer.DeserializePayload <DiscoveryCriteria>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager()
                    .DiscoverTests(discoveryCriteria, discoveryEventsHandler), 0);

                break;
            }

            case MessageType.ExecutionInitialize:
            {
                EqtTrace.Info("Execution Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var testInitializeEventsHandler = new TestInitializeEventsHandler(this);
                var pathToAdditionalExtensions  = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions, testInitializeEventsHandler), 0);
                break;
            }

            case MessageType.StartTestExecutionWithSources:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithSources = this.dataSerializer.DeserializePayload <TestRunCriteriaWithSources>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithSources.AdapterSourceMap,
                        testRunCriteriaWithSources.Package,
                        testRunCriteriaWithSources.RunSettings,
                        testRunCriteriaWithSources.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithSources.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.StartTestExecutionWithTests:
            {
                //System.Diagnostics.Debugger.Launch();
                //System.Diagnostics.Debugger.Break();

                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithTests =
                    this.dataSerializer.DeserializePayload <TestRunCriteriaWithTests>(message);

                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithTests.Tests,
                        testRunCriteriaWithTests.Package,
                        testRunCriteriaWithTests.RunSettings,
                        testRunCriteriaWithTests.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithTests.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.CancelTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Cancel(new TestRunEventsHandler(this));
                break;

            case MessageType.LaunchAdapterProcessWithDebuggerAttachedCallback:
                this.onLaunchAdapterProcessWithDebuggerAttachedAckReceived?.Invoke(message);
                break;

            case MessageType.AttachDebuggerCallback:
                this.onAttachDebuggerAckRecieved?.Invoke(message);
                break;

            case MessageType.AbortTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Abort(new TestRunEventsHandler(this));
                break;

            case MessageType.SessionEnd:
            {
                EqtTrace.Info("Session End message received from server. Closing the connection.");
                sessionCompleted.Set();
                this.Close();
                break;
            }

            case MessageType.SessionAbort:
            {
                // Don't do anything for now.
                break;
            }

            default:
            {
                EqtTrace.Info("Invalid Message types");
                break;
            }
            }
        }
Example #3
0
        /// <summary>
        /// Run Tests with given a set of test cases.
        /// </summary>
        /// <param name="testRunRequestPayload">TestRun request Payload</param>
        /// <param name="testHostLauncher">TestHost Launcher for the run</param>
        /// <param name="testRunEventsRegistrar">event registrar for run events</param>
        /// <param name="protocolConfig">Protocol related information</param>
        /// <returns>True, if successful</returns>
        public bool RunTests(TestRunRequestPayload testRunRequestPayload, ITestHostLauncher testHostLauncher, ITestRunEventsRegistrar testRunEventsRegistrar, ProtocolConfig protocolConfig)
        {
            EqtTrace.Info("TestRequestManager.RunTests: run tests started.");

            TestRunCriteria runCriteria = null;
            var             runsettings = testRunRequestPayload.RunSettings;

            if (testRunRequestPayload.TestPlatformOptions != null)
            {
                this.telemetryOptedIn = testRunRequestPayload.TestPlatformOptions.CollectMetrics;
            }

            var requestData = this.GetRequestData(protocolConfig);

            // Get sources to auto detect fx and arch for both run selected or run all scenario.
            var sources = GetSources(testRunRequestPayload);

            if (this.UpdateRunSettingsIfRequired(runsettings, sources, out string updatedRunsettings))
            {
                runsettings = updatedRunsettings;
            }

            if (InferRunSettingsHelper.IsTestSettingsEnabled(runsettings))
            {
                bool throwException = false;
                if (this.commandLineOptions.EnableCodeCoverage)
                {
                    var dataCollectorsFriendlyNames = XmlRunSettingsUtilities.GetDataCollectorsFriendlyName(runsettings);
                    if (dataCollectorsFriendlyNames.Count >= 2)
                    {
                        throwException = true;
                    }
                }
                else if (XmlRunSettingsUtilities.IsDataCollectionEnabled(runsettings))
                {
                    throwException = true;
                }

                if (throwException)
                {
                    throw new SettingsException(string.Format(Resources.RunsettingsWithDCErrorMessage, runsettings));
                }
            }

            var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings);
            var batchSize        = runConfiguration.BatchSize;

            if (requestData.IsTelemetryOptedIn)
            {
                // Collect Metrics
                this.CollectMetrics(requestData, runConfiguration);

                // Collect Commands
                this.LogCommandsTelemetryPoints(requestData);
            }

            if (!commandLineOptions.IsDesignMode)
            {
                // Generate fakes settings only for command line scenarios. In case of
                // Editors/IDEs, this responsibility is with the caller.
                GenerateFakesUtilities.GenerateFakesSettings(this.commandLineOptions, this.commandLineOptions.Sources.ToList(), ref runsettings);
            }

            if (testRunRequestPayload.Sources != null && testRunRequestPayload.Sources.Any())
            {
                runCriteria = new TestRunCriteria(
                    testRunRequestPayload.Sources,
                    batchSize,
                    testRunRequestPayload.KeepAlive,
                    runsettings,
                    this.commandLineOptions.TestStatsEventTimeout,
                    testHostLauncher);
                runCriteria.TestCaseFilter = testRunRequestPayload.TestPlatformOptions?.TestCaseFilter;
                runCriteria.FilterOptions  = testRunRequestPayload.TestPlatformOptions?.FilterOptions;
            }
            else
            {
                runCriteria = new TestRunCriteria(
                    testRunRequestPayload.TestCases,
                    batchSize,
                    testRunRequestPayload.KeepAlive,
                    runsettings,
                    this.commandLineOptions.TestStatsEventTimeout,
                    testHostLauncher);
            }

            var success = this.RunTests(requestData, runCriteria, testRunEventsRegistrar);

            EqtTrace.Info("TestRequestManager.RunTests: run tests completed, sucessful: {0}.", success);
            this.testPlatformEventSource.ExecutionRequestStop();

            // Post the run complete event
            this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestExecutionCompleteEvent, requestData.MetricsCollection.Metrics);

            return(success);
        }
Example #4
0
 /// <summary>
 /// Cancel the test discovery.
 /// </summary>
 public void CancelDiscovery()
 {
     EqtTrace.Info("TestRequestManager.CancelTestDiscovery: Sending cancel request.");
     this.currentDiscoveryRequest?.Abort();
 }
Example #5
0
 /// <inheritdoc/>
 public void CancelTestRunAttachmentsProcessing()
 {
     EqtTrace.Info("TestRequestManager.CancelTestRunAttachmentsProcessing: Sending cancel request.");
     this.currentAttachmentsProcessingCancellationTokenSource?.Cancel();
 }
Example #6
0
        /// <summary>
        /// Discover Tests given a list of sources, run settings.
        /// </summary>
        /// <param name="discoveryPayload">Discovery payload</param>
        /// <param name="discoveryEventsRegistrar">EventHandler for discovered tests</param>
        /// <param name="protocolConfig">Protocol related information</param>
        /// <returns>True, if successful</returns>
        public bool DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar discoveryEventsRegistrar, ProtocolConfig protocolConfig)
        {
            EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests started.");

            bool success = false;

            var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(discoveryPayload.RunSettings);
            var batchSize        = runConfiguration.BatchSize;

            var runsettings = discoveryPayload.RunSettings;

            if (this.UpdateRunSettingsIfRequired(runsettings, out string updatedRunsettings))
            {
                runsettings = updatedRunsettings;
            }

            runsettings = UpdateExtensionsFolderInRunSettings(runsettings);

            // create discovery request
            var criteria = new DiscoveryCriteria(discoveryPayload.Sources, batchSize, this.commandLineOptions.TestStatsEventTimeout, runsettings);

            using (IDiscoveryRequest discoveryRequest = this.testPlatform.CreateDiscoveryRequest(criteria, protocolConfig))
            {
                try
                {
                    this.testLoggerManager?.RegisterDiscoveryEvents(discoveryRequest);
                    discoveryEventsRegistrar?.RegisterDiscoveryEvents(discoveryRequest);

                    this.testPlatformEventSource.DiscoveryRequestStart();

                    discoveryRequest.DiscoverAsync();
                    discoveryRequest.WaitForCompletion();

                    success = true;
                }
                catch (Exception ex)
                {
                    if (ex is TestPlatformException ||
                        ex is SettingsException ||
                        ex is InvalidOperationException)
                    {
#if TODO
                        Utilities.RaiseTestRunError(testLoggerManager, null, ex);
#endif
                        success = false;
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    this.testLoggerManager?.UnregisterDiscoveryEvents(discoveryRequest);
                    discoveryEventsRegistrar?.UnregisterDiscoveryEvents(discoveryRequest);
                }
            }

            EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests completed, successful: {0}.", success);
            this.testPlatformEventSource.DiscoveryRequestStop();
            return(success);
        }
Example #7
0
        /// <summary>
        /// Discover Tests given a list of sources, run settings.
        /// </summary>
        /// <param name="discoveryPayload">Discovery payload</param>
        /// <param name="discoveryEventsRegistrar">EventHandler for discovered tests</param>
        /// <param name="protocolConfig">Protocol related information</param>
        /// <returns>True, if successful</returns>
        public void DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar discoveryEventsRegistrar, ProtocolConfig protocolConfig)
        {
            EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests started.");

            var runsettings = discoveryPayload.RunSettings;

            if (discoveryPayload.TestPlatformOptions != null)
            {
                this.telemetryOptedIn = discoveryPayload.TestPlatformOptions.CollectMetrics;
            }

            var requestData = this.GetRequestData(protocolConfig);

            if (this.UpdateRunSettingsIfRequired(runsettings, discoveryPayload.Sources?.ToList(), discoveryEventsRegistrar, out string updatedRunsettings))
            {
                runsettings = updatedRunsettings;
            }

            var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings);
            var batchSize        = runConfiguration.BatchSize;
            var testCaseFilterFromRunsettings = runConfiguration.TestCaseFilter;

            if (requestData.IsTelemetryOptedIn)
            {
                // Collect Metrics
                this.CollectMetrics(requestData, runConfiguration);

                // Collect Commands
                this.LogCommandsTelemetryPoints(requestData);
            }

            // create discovery request
            var criteria = new DiscoveryCriteria(discoveryPayload.Sources, batchSize, this.commandLineOptions.TestStatsEventTimeout, runsettings)
            {
                TestCaseFilter = this.commandLineOptions.TestCaseFilterValue ?? testCaseFilterFromRunsettings
            };

            // Make sure to run the run request inside a lock as the below section is not thread-safe
            // There can be only one discovery or execution request at a given point in time
            lock (this.syncObject)
            {
                try
                {
                    EqtTrace.Info("TestRequestManager.DiscoverTests: Synchronization context taken");

                    this.currentDiscoveryRequest = this.testPlatform.CreateDiscoveryRequest(requestData, criteria, discoveryPayload.TestPlatformOptions);
                    discoveryEventsRegistrar?.RegisterDiscoveryEvents(this.currentDiscoveryRequest);

                    // Notify start of discovery start
                    this.testPlatformEventSource.DiscoveryRequestStart();

                    // Start the discovery of tests and wait for completion
                    this.currentDiscoveryRequest.DiscoverAsync();
                    this.currentDiscoveryRequest.WaitForCompletion();
                }
                finally
                {
                    if (this.currentDiscoveryRequest != null)
                    {
                        // Dispose the discovery request and unregister for events
                        discoveryEventsRegistrar?.UnregisterDiscoveryEvents(currentDiscoveryRequest);
                        this.currentDiscoveryRequest.Dispose();
                        this.currentDiscoveryRequest = null;
                    }

                    EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests completed.");
                    this.testPlatformEventSource.DiscoveryRequestStop();

                    // Posts the Discovery Complete event.
                    this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestDiscoveryCompleteEvent, requestData.MetricsCollection.Metrics);
                }
            }
        }
Example #8
0
        private Assembly SearchAndLoadAssembly(string assemblyPath, string assemblyName, AssemblyName requestedName, bool isReflectionOnly)
        {
            try
            {
                if (!this.DoesFileExist(assemblyPath))
                {
                    return(null);
                }

                var foundName = AssemblyName.GetAssemblyName(assemblyPath);

                if (!RequestedAssemblyNameMatchesFound(requestedName, foundName))
                {
                    return(null); // File exists but version/public key is wrong. Try next extension.
                }

                Assembly assembly;

                if (isReflectionOnly)
                {
                    assembly = this.ReflectionOnlyLoadAssemblyFrom(assemblyPath);
                    this.reflectionOnlyResolvedAssemblies[assemblyName] = assembly;
                }
                else
                {
                    assembly = this.LoadAssemblyFrom(assemblyPath);
                    this.resolvedAssemblies[assemblyName] = assembly;
                }

                this.SafeLog(
                    assemblyName,
                    () =>
                {
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("AssemblyResolver: Resolved assembly: {0}. ", assemblyName);
                    }
                });
                return(assembly);
            }
            catch (FileLoadException ex)
            {
                this.SafeLog(
                    assemblyName,
                    () =>
                {
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("AssemblyResolver: Failed to load assembly: {0}. Reason:{1} ", assemblyName, ex);
                    }
                });

                // Re-throw FileLoadException, because this exception means that the assembly
                // was found, but could not be loaded. This will allow us to report a more
                // specific error message to the user for things like access denied.
                throw;
            }
            catch (Exception ex)
            {
                // For all other exceptions, try the next extension.
                this.SafeLog(
                    assemblyName,
                    () =>
                {
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("AssemblyResolver: Failed to load assembly: {0}. Reason:{1} ", assemblyName, ex);
                    }
                });
            }

            return(null);
        }
        public void Invoke(IDictionary <string, string> argsDictionary)
        {
            DefaultEngineInvoker.InitializeEqtTrace(argsDictionary);

            if (EqtTrace.IsVerboseEnabled)
            {
                var version = typeof(DefaultEngineInvoker)
                              .GetTypeInfo()
                              .Assembly
                              .GetCustomAttribute <AssemblyInformationalVersionAttribute>()?.InformationalVersion;
                EqtTrace.Verbose($"Version: { version }");
            }

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("DefaultEngineInvoker.Invoke: Testhost process started with args :{0}",
                              string.Join(",", argsDictionary));
#if NETFRAMEWORK
                var appConfigText =
                    System.IO.File.ReadAllText(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
                EqtTrace.Info("DefaultEngineInvoker: Using Application Configuration: '{0}'", appConfigText);
#endif
            }

#if NETCOREAPP
            TestHostTraceListener.Setup();
#endif

            this.SetParentProcessExitCallback(argsDictionary);

            this.requestHandler.ConnectionInfo =
                DefaultEngineInvoker.GetConnectionInfo(argsDictionary);

            // Initialize Communication with vstest.console
            this.requestHandler.InitializeCommunication();

            // skipping because 0 is the default value, and also the value the the callers use when they
            // call with the parameter specified, but without providing an actual port
            var dcPort = CommandLineArgumentsHelper.GetIntArgFromDict(argsDictionary, DataCollectionPortArgument);
            if (dcPort > 0)
            {
                this.ConnectToDatacollector(dcPort);
            }

            var requestData = DefaultEngineInvoker.GetRequestData(argsDictionary);

            // Start processing async in a different task
            EqtTrace.Info("DefaultEngineInvoker.Invoke: Start Request Processing.");
            try
            {
                this.StartProcessingAsync(requestHandler, new TestHostManagerFactory(requestData)).Wait();
            }
            finally
            {
                if (dcPort > 0)
                {
                    // Close datacollector communication.
                    this.dataCollectionTestCaseEventSender.Close();
                }

                this.requestHandler.Dispose();
            }
        }
Example #10
0
        /// <summary>
        /// It will search for a particular assembly in the given list of directory.
        /// </summary>
        /// <param name="searchDirectorypaths"> The search Directorypaths. </param>
        /// <param name="name"> The name. </param>
        /// <param name="isReflectionOnly"> Indicates whether this is called under a Reflection Only Load context. </param>
        /// <returns> The <see cref="Assembly"/>. </returns>
        protected virtual Assembly SearchAssembly(List <string> searchDirectorypaths, string name, bool isReflectionOnly)
        {
            if (searchDirectorypaths == null || searchDirectorypaths.Count == 0)
            {
                return(null);
            }

            // args.Name is like: "Microsoft.VisualStudio.TestTools.Common, Version=[VersionMajor].0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
            AssemblyName requestedName = null;

            try
            {
                // Can throw ArgumentException, FileLoadException if arg is empty/wrong format, etc. Should not return null.
                requestedName = new AssemblyName(name);
            }
            catch (Exception ex)
            {
                this.SafeLog(
                    name,
                    () =>
                {
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info(
                            "AssemblyResolver: {0}: Failed to create assemblyName. Reason:{1} ",
                            name,
                            ex);
                    }
                });

                return(null);
            }

            Debug.Assert(requestedName != null && !string.IsNullOrEmpty(requestedName.Name), "AssemblyResolver.OnResolve: requested is null or name is empty!");

            foreach (var dir in searchDirectorypaths)
            {
                if (string.IsNullOrEmpty(dir))
                {
                    continue;
                }

                this.SafeLog(
                    name,
                    () =>
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose("AssemblyResolver: Searching assembly: {0} in the directory: {1}", requestedName.Name, dir);
                    }
                });

                foreach (var extension in new string[] { ".dll", ".exe" })
                {
                    var assemblyPath = Path.Combine(dir, requestedName.Name + extension);

                    var assembly = this.SearchAndLoadAssembly(assemblyPath, name, requestedName, isReflectionOnly);
                    if (assembly != null)
                    {
                        return(assembly);
                    }
                }
            }

            return(null);
        }
Example #11
0
        private Assembly OnResolveInternal(object senderAppDomain, ResolveEventArgs args, bool isReflectionOnly)
        {
            if (string.IsNullOrEmpty(args?.Name))
            {
                Debug.Fail("AssemblyResolver.OnResolve: args.Name is null or empty.");
                return(null);
            }

            this.SafeLog(
                args.Name,
                () =>
            {
                if (EqtTrace.IsInfoEnabled)
                {
                    EqtTrace.Info("AssemblyResolver: Resolving assembly: {0}.", args.Name);
                }
            });

            string assemblyNameToLoad = AppDomain.CurrentDomain.ApplyPolicy(args.Name);

            this.SafeLog(
                assemblyNameToLoad,
                () =>
            {
                if (EqtTrace.IsInfoEnabled)
                {
                    EqtTrace.Info("AssemblyResolver: Resolving assembly after applying policy: {0}.", assemblyNameToLoad);
                }
            });

            lock (this.syncLock)
            {
                // Since both normal and reflection only cache are accessed in same block, putting only one lock should be sufficient.
                if (this.TryLoadFromCache(assemblyNameToLoad, isReflectionOnly, out var assembly))
                {
                    return(assembly);
                }

                assembly = this.SearchAssembly(this.searchDirectories, assemblyNameToLoad, isReflectionOnly);

                if (assembly != null)
                {
                    return(assembly);
                }

                if (this.directoryList != null && this.directoryList.Any())
                {
                    // required assembly is not present in searchDirectories??
                    // see, if we can find it in user specified search directories.
                    while (assembly == null && this.directoryList.Count > 0)
                    {
                        // instead of loading whole search directory in one time, we are adding directory on the basis of need
                        var currentNode = this.directoryList.Dequeue();

                        List <string> increamentalSearchDirectory = new List <string>();

                        if (this.DoesDirectoryExist(currentNode.DirectoryPath))
                        {
                            increamentalSearchDirectory.Add(currentNode.DirectoryPath);

                            if (currentNode.IncludeSubDirectories)
                            {
                                // Add all its sub-directory in depth first search order.
                                this.AddSubdirectories(currentNode.DirectoryPath, increamentalSearchDirectory);
                            }

                            // Add this directory list in this.searchDirectories so that when we will try to resolve some other
                            // assembly, then it will look in this whole directory first.
                            this.searchDirectories.AddRange(increamentalSearchDirectory);

                            assembly = this.SearchAssembly(increamentalSearchDirectory, assemblyNameToLoad, isReflectionOnly);
                        }
                        else
                        {
                            // generate warning that path does not exist.
                            this.SafeLog(
                                assemblyNameToLoad,
                                () =>
                            {
                                if (EqtTrace.IsWarningEnabled)
                                {
                                    EqtTrace.Warning(
                                        "The Directory: {0}, does not exist",
                                        currentNode.DirectoryPath);
                                }
                            });
                        }
                    }

                    if (assembly != null)
                    {
                        return(assembly);
                    }
                }

                // Try for default load for System dlls that can't be found in search paths. Needs to loaded just by name.
                try
                {
                    if (isReflectionOnly)
                    {
                        // Put it in the resolved assembly cache so that if the Load call below
                        // triggers another assembly resolution, then we don't end up in stack overflow.
                        this.reflectionOnlyResolvedAssemblies[assemblyNameToLoad] = null;

                        assembly = Assembly.ReflectionOnlyLoad(assemblyNameToLoad);

                        if (assembly != null)
                        {
                            this.reflectionOnlyResolvedAssemblies[assemblyNameToLoad] = assembly;
                        }
                    }
                    else
                    {
                        // Put it in the resolved assembly cache so that if the Load call below
                        // triggers another assembly resolution, then we don't end up in stack overflow.
                        this.resolvedAssemblies[assemblyNameToLoad] = null;

                        assembly = Assembly.Load(assemblyNameToLoad);

                        if (assembly != null)
                        {
                            this.resolvedAssemblies[assemblyNameToLoad] = assembly;
                        }
                    }

                    return(assembly);
                }
                catch (Exception ex)
                {
                    this.SafeLog(
                        args?.Name,
                        () =>
                    {
                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("AssemblyResolver: {0}: Failed to load assembly. Reason: {1}", assemblyNameToLoad, ex);
                        }
                    });
                }

                return(assembly);
            }
        }
Example #12
0
 /// <summary>
 /// Launches a process with a given process info under debugger
 /// Adapter get to call into this to launch any additional processes under debugger
 /// </summary>
 /// <param name="testProcessStartInfo">Process start info</param>
 /// <returns>ProcessId of the launched process</returns>
 public int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testProcessStartInfo)
 {
     EqtTrace.Info("Sending LaunchProcessWithDebuggerAttached on additional test process: {0}", testProcessStartInfo?.FileName);
     return(this.requestHandler.LaunchProcessWithDebuggerAttached(testProcessStartInfo));
 }
Example #13
0
 /// <summary>
 /// Handle test run complete.
 /// </summary>
 /// <param name="testRunCompleteArgs"> The test run complete args. </param>
 /// <param name="lastChunkArgs"> The last chunk args. </param>
 /// <param name="runContextAttachments"> The run context attachments. </param>
 /// <param name="executorUris"> The executor uris. </param>
 public void HandleTestRunComplete(TestRunCompleteEventArgs testRunCompleteArgs, TestRunChangedEventArgs lastChunkArgs, ICollection <AttachmentSet> runContextAttachments, ICollection <string> executorUris)
 {
     EqtTrace.Info("Sending test run complete");
     this.requestHandler.SendExecutionComplete(testRunCompleteArgs, lastChunkArgs, runContextAttachments, executorUris);
 }
Example #14
0
 /// <summary>
 /// Handle test run stats change.
 /// </summary>
 /// <param name="testRunChangedArgs"> The test run changed args. </param>
 public void HandleTestRunStatsChange(TestRunChangedEventArgs testRunChangedArgs)
 {
     EqtTrace.Info("Sending test run statistics");
     this.requestHandler.SendTestRunStatistics(testRunChangedArgs);
 }
Example #15
0
        /// <summary>
        /// Invoked when test run is complete
        /// </summary>
        public void HandleTestRunComplete(TestRunCompleteEventArgs runCompleteArgs, TestRunChangedEventArgs lastChunkArgs, ICollection <AttachmentSet> runContextAttachments, ICollection <string> executorUris)
        {
            if (runCompleteArgs == null)
            {
                throw new ArgumentNullException(nameof(runCompleteArgs));
            }

            bool isAborted  = runCompleteArgs.IsAborted;
            bool isCanceled = runCompleteArgs.IsCanceled;

            EqtTrace.Verbose("TestRunRequest:TestRunComplete: Starting. IsAborted:{0} IsCanceled:{1}.", isAborted, isCanceled);

            lock (this.syncObject)
            {
                // If this object is disposed, don't do anything
                if (this.disposed)
                {
                    EqtTrace.Warning("TestRunRequest.TestRunComplete: Ignoring as the object is disposed.");
                    return;
                }

                if (this.runCompletionEvent.WaitOne(0))
                {
                    EqtTrace.Info("TestRunRequest:TestRunComplete:Ignoring duplicate event. IsAborted:{0} IsCanceled:{1}.", isAborted, isCanceled);
                    return;
                }

                // Disposing off the resources held by the execution manager so that the test host process can shut down.
                this.ExecutionManager?.Close();

                try
                {
                    this.runRequestTimeTracker.Stop();

                    if (lastChunkArgs != null)
                    {
                        // Raised the changed event also
                        this.LoggerManager.HandleTestRunStatsChange(lastChunkArgs);
                        this.OnRunStatsChange.SafeInvoke(this, lastChunkArgs, "TestRun.RunStatsChanged");
                    }

                    TestRunCompleteEventArgs runCompletedEvent =
                        new TestRunCompleteEventArgs(
                            runCompleteArgs.TestRunStatistics,
                            runCompleteArgs.IsCanceled,
                            runCompleteArgs.IsAborted,
                            runCompleteArgs.Error,
                            // This is required as TMI adapter is sending attachments as List which cannot be type casted to Collection.
                            runContextAttachments != null ? new Collection <AttachmentSet>(runContextAttachments.ToList()) : null,
                            this.runRequestTimeTracker.Elapsed);

                    // Ignore the time sent (runCompleteArgs.ElapsedTimeInRunningTests)
                    // by either engines - as both calculate at different points
                    // If we use them, it would be an incorrect comparison between TAEF and Rocksteady
                    this.LoggerManager.HandleTestRunComplete(runCompletedEvent);
                    this.OnRunCompletion.SafeInvoke(this, runCompletedEvent, "TestRun.TestRunComplete");
                }
                finally
                {
                    if (isCanceled)
                    {
                        this.State = TestRunState.Canceled;
                    }
                    else if (isAborted)
                    {
                        this.State = TestRunState.Aborted;
                    }
                    else
                    {
                        this.State = TestRunState.Completed;
                    }

                    // Notify the waiting handle that run is complete
                    this.runCompletionEvent.Set();


                    var executionTotalTimeTaken = DateTime.UtcNow - this.executionStartTime;

                    // Fill in the time taken to complete the run
                    this.requestData.MetricsCollection.Add(TelemetryDataConstants.TimeTakenInSecForRun, executionTotalTimeTaken.TotalSeconds);

                    // Fill in the Metrics From Test Host Process
                    var metrics = runCompleteArgs.Metrics;
                    if (metrics != null && metrics.Count != 0)
                    {
                        foreach (var metric in metrics)
                        {
                            this.requestData.MetricsCollection.Add(metric.Key, metric.Value);
                        }
                    }
                }

                EqtTrace.Info("TestRunRequest:TestRunComplete: Completed.");
            }
        }
Example #16
0
        /// <summary>
        /// Process Requests from the IDE
        /// </summary>
        /// <param name="testRequestManager">
        /// The test Request Manager.
        /// </param>
        private void ProcessRequests(ITestRequestManager testRequestManager)
        {
            var isSessionEnd = false;

            do
            {
                try
                {
                    var message = this.communicationManager.ReceiveMessage();

                    EqtTrace.Info("DesignModeClient: Processing Message of message type: {0}", message.MessageType);
                    switch (message.MessageType)
                    {
                    case MessageType.VersionCheck:
                    {
                        var version = this.dataSerializer.DeserializePayload <int>(message);
                        this.protocolConfig.Version = Math.Min(version, this.protocolConfig.Version);
                        this.communicationManager.SendMessage(MessageType.VersionCheck, this.protocolConfig.Version);
                        break;
                    }

                    case MessageType.ExtensionsInitialize:
                    {
                        var extensionPaths = this.communicationManager.DeserializePayload <IEnumerable <string> >(message);
                        testRequestManager.InitializeExtensions(extensionPaths);
                        break;
                    }

                    case MessageType.StartDiscovery:
                    {
                        var discoveryPayload = this.dataSerializer.DeserializePayload <DiscoveryRequestPayload>(message);
                        this.StartDiscovery(discoveryPayload, testRequestManager);
                        break;
                    }

                    case MessageType.GetTestRunnerProcessStartInfoForRunAll:
                    case MessageType.GetTestRunnerProcessStartInfoForRunSelected:
                    {
                        var testRunPayload =
                            this.communicationManager.DeserializePayload <TestRunRequestPayload>(
                                message);
                        this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: true);
                        break;
                    }

                    case MessageType.TestRunAllSourcesWithDefaultHost:
                    case MessageType.TestRunSelectedTestCasesDefaultHost:
                    {
                        var testRunPayload =
                            this.communicationManager.DeserializePayload <TestRunRequestPayload>(
                                message);
                        this.StartTestRun(testRunPayload, testRequestManager, skipTestHostLaunch: false);
                        break;
                    }

                    case MessageType.CancelTestRun:
                    {
                        testRequestManager.CancelTestRun();
                        break;
                    }

                    case MessageType.AbortTestRun:
                    {
                        testRequestManager.AbortTestRun();
                        break;
                    }

                    case MessageType.CustomTestHostLaunchCallback:
                    {
                        this.onAckMessageReceived?.Invoke(message);
                        break;
                    }

                    case MessageType.SessionEnd:
                    {
                        EqtTrace.Info("DesignModeClient: Session End message received from server. Closing the connection.");
                        isSessionEnd = true;
                        this.Dispose();
                        break;
                    }

                    default:
                    {
                        EqtTrace.Info("DesignModeClient: Invalid Message received: {0}", message);
                        break;
                    }
                    }
                }
                catch (Exception ex)
                {
                    EqtTrace.Error("DesignModeClient: Error processing request: {0}", ex);
                    isSessionEnd = true;
                    this.Dispose();
                }
            }while (!isSessionEnd);
        }
Example #17
0
 /// <summary>
 /// Initializes the extensions while probing additional paths.
 /// </summary>
 /// <param name="pathToAdditionalExtensions">Paths to Additional extensions</param>
 public void InitializeExtensions(IEnumerable <string> pathToAdditionalExtensions)
 {
     EqtTrace.Info("TestRequestManager.InitializeExtensions: Initialize extensions started.");
     this.testPlatform.UpdateExtensions(pathToAdditionalExtensions, false);
     EqtTrace.Info("TestRequestManager.InitializeExtensions: Initialize extensions completed.");
 }
Example #18
0
        /// <summary>
        /// Called when Session End event is invoked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="args">SessionEndEventArgs</param>
        private void SessionEndedHandler(object sender, SessionEndEventArgs args)
        {
            this.ResetInactivityTimer();

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("Blame Collector : Session End");
            }

            try
            {
                // If the last test crashes, it will not invoke a test case end and therefore
                // In case of crash testStartCount will be greater than testEndCount and we need to write the sequence
                // And send the attachment
                if (this.testStartCount > this.testEndCount)
                {
                    var filepath = Path.Combine(this.GetResultsDirectory(), Constants.AttachmentFileName + "_" + this.attachmentGuid);
                    filepath = this.blameReaderWriter.WriteTestSequence(this.testSequence, this.testObjectDictionary, filepath);
                    var fileTranferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, filepath, true);
                    this.dataCollectionSink.SendFileAsync(fileTranferInformation);
                }

                if (this.collectProcessDumpOnTrigger)
                {
                    // If there was a test case crash or if we need to collect dump on process exit.
                    if (this.testStartCount > this.testEndCount || this.collectDumpAlways)
                    {
                        try
                        {
                            var dumpFile = this.processDumpUtility.GetDumpFile();
                            if (!string.IsNullOrEmpty(dumpFile))
                            {
                                var fileTranferInformation = new FileTransferInformation(this.context.SessionDataCollectionContext, dumpFile, true);
                                this.dataCollectionSink.SendFileAsync(fileTranferInformation);
                            }
                            else
                            {
                                EqtTrace.Warning("BlameCollector.SessionEndedHandler: blame:CollectDump was enabled but dump file was not generated.");
                                this.logger.LogWarning(args.Context, Resources.Resources.ProcDumpNotGenerated);
                            }
                        }
                        catch (FileNotFoundException ex)
                        {
                            EqtTrace.Warning(ex.ToString());
                            this.logger.LogWarning(args.Context, ex.ToString());
                        }
                    }
                }
            }
            finally
            {
                // Attempt to terminate the proc dump process if proc dump was enabled
                if (this.collectProcessDumpOnTrigger)
                {
                    this.processDumpUtility.DetachFromTargetProcess(this.testHostProcessId);
                    this.processDumpUtility.TerminateProcess();
                }

                this.DeregisterEvents();
            }
        }
Example #19
0
        public void OnMessageReceived(object sender, MessageReceivedEventArgs messageReceivedArgs)
        {
            var message = this.dataSerializer.DeserializeMessage(messageReceivedArgs.Data);

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("TestRequestHandler.ProcessRequests: received message: {0}", message);
            }

            switch (message.MessageType)
            {
            case MessageType.VersionCheck:
                var version = this.dataSerializer.DeserializePayload <int>(message);
                this.protocolVersion = Math.Min(version, highestSupportedVersion);

                // Send the negotiated protocol to request sender
                this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion));

                // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized
                if (!string.IsNullOrEmpty(EqtTrace.LogFile))
                {
                    this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile));
                }
                else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
                {
                    this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization);
                }
                break;

            case MessageType.DiscoveryInitialize:
            {
                EqtTrace.Info("Discovery Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var pathToAdditionalExtensions = message.Payload.ToObject <IEnumerable <string> >();
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions), 0);
                break;
            }

            case MessageType.StartDiscovery:
            {
                EqtTrace.Info("Discovery started.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler = new TestDiscoveryEventHandler(this);
                var discoveryCriteria      = message.Payload.ToObject <DiscoveryCriteria>();
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager()
                    .DiscoverTests(discoveryCriteria, discoveryEventsHandler), 0);

                break;
            }

            case MessageType.ExecutionInitialize:
            {
                EqtTrace.Info("Discovery Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var pathToAdditionalExtensions = message.Payload.ToObject <IEnumerable <string> >();
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions), 0);
                break;
            }

            case MessageType.StartTestExecutionWithSources:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithSources = message.Payload.ToObject <TestRunCriteriaWithSources>();
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithSources.AdapterSourceMap,
                        testRunCriteriaWithSources.Package,
                        testRunCriteriaWithSources.RunSettings,
                        testRunCriteriaWithSources.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithSources.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.StartTestExecutionWithTests:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithTests =
                    this.dataSerializer.DeserializePayload <TestRunCriteriaWithTests>(message);

                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithTests.Tests,
                        testRunCriteriaWithTests.Package,
                        testRunCriteriaWithTests.RunSettings,
                        testRunCriteriaWithTests.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithTests.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.CancelTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Cancel();
                break;

            case MessageType.LaunchAdapterProcessWithDebuggerAttachedCallback:
                this.onAckMessageRecieved?.Invoke(message);
                break;

            case MessageType.AbortTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Abort();
                break;

            case MessageType.SessionEnd:
            {
                EqtTrace.Info("Session End message received from server. Closing the connection.");
                sessionCompleted.Set();
                this.Close();
                break;
            }

            case MessageType.SessionAbort:
            {
                // Dont do anything for now.
                break;
            }

            default:
            {
                EqtTrace.Info("Invalid Message types");
                break;
            }
            }
        }
        /// <inheritDoc />
        public void ProcessRequests()
        {
            var isSessionEnd = false;

            do
            {
                var message = this.communicationManager.ReceiveMessage();
                switch (message.MessageType)
                {
                case MessageType.DataCollectionTestStart:
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler: Test case starting.");
                    }

                    var testCaseStartEventArgs = message.Payload.ToObject <TestCaseStartEventArgs>();
                    this.dataCollectionManager.TestCaseStarted(testCaseStartEventArgs);

                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler: Test case started.");
                    }

                    break;

                case MessageType.DataCollectionTestEnd:
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler : Test case completing.");
                    }

                    var testCaseEndEventArgs = message.Payload.ToObject <TestCaseEndEventArgs>();
                    var attachmentSets       = this.dataCollectionManager.TestCaseEnded(testCaseEndEventArgs);
                    this.communicationManager.SendMessage(MessageType.DataCollectionTestEndResult, attachmentSets);

                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler: Test case completed");
                    }

                    break;

                case MessageType.SessionEnd:
                    isSessionEnd = true;

                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler: Test session ended");
                    }

                    this.Close();

                    break;

                default:
                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("DataCollectionTestCaseEventHandler: Invalid Message types");
                    }

                    break;
                }
            }while (!isSessionEnd);
        }
Example #21
0
 /// <summary>
 /// Cancel the test run.
 /// </summary>
 public void CancelTestRun()
 {
     EqtTrace.Info("TestRequestManager.CancelTestRun: Sending cancel request.");
     this.currentTestRunRequest?.CancelAsync();
 }
        /// <summary>
        /// Triggers the execution for the next data object on the concurrent executor
        /// Each concurrent executor calls this method, once its completed working on previous data
        /// </summary>
        /// <param name="proxyExecutionManager">Proxy execution manager instance.</param>
        /// <returns>True, if execution triggered</returns>
        private void StartTestRunOnConcurrentManager(IProxyExecutionManager proxyExecutionManager)
        {
            TestRunCriteria testRunCriteria = null;

            if (!this.hasSpecificTestsRun)
            {
                if (this.TryFetchNextSource(this.sourceEnumerator, out string nextSource))
                {
                    EqtTrace.Info("ProxyParallelExecutionManager: Triggering test run for next source: {0}", nextSource);

                    testRunCriteria = new TestRunCriteria(
                        new[] { nextSource },
                        this.actualTestRunCriteria.FrequencyOfRunStatsChangeEvent,
                        this.actualTestRunCriteria.KeepAlive,
                        this.actualTestRunCriteria.TestRunSettings,
                        this.actualTestRunCriteria.RunStatsChangeEventTimeout,
                        this.actualTestRunCriteria.TestHostLauncher)
                    {
                        TestCaseFilter = this.actualTestRunCriteria.TestCaseFilter
                    };
                }
            }
            else
            {
                if (this.TryFetchNextSource(this.testCaseListEnumerator, out List <TestCase> nextSetOfTests))
                {
                    EqtTrace.Info("ProxyParallelExecutionManager: Triggering test run for next source: {0}", nextSetOfTests?.FirstOrDefault()?.Source);

                    testRunCriteria = new TestRunCriteria(
                        nextSetOfTests,
                        this.actualTestRunCriteria.FrequencyOfRunStatsChangeEvent,
                        this.actualTestRunCriteria.KeepAlive,
                        this.actualTestRunCriteria.TestRunSettings,
                        this.actualTestRunCriteria.RunStatsChangeEventTimeout,
                        this.actualTestRunCriteria.TestHostLauncher);
                }
            }

            if (testRunCriteria != null)
            {
                if (!proxyExecutionManager.IsInitialized)
                {
                    proxyExecutionManager.Initialize();
                }

                Task.Run(() =>
                {
                    Interlocked.Increment(ref this.runStartedClients);
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose("ParallelProxyExecutionManager: Execution started. Started clients: " + this.runStartedClients);
                    }

                    proxyExecutionManager.StartTestRun(testRunCriteria, this.GetHandlerForGivenManager(proxyExecutionManager));
                })
                .ContinueWith(t =>
                {
                    // Just in case, the actual execution couldn't start for an instance. Ensure that
                    // we call execution complete since we have already fetched a source. Otherwise
                    // execution will not terminate
                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning("ParallelProxyExecutionManager: Failed to trigger execution. Exception: " + t.Exception);
                    }

                    // Send a run complete to caller. Similar logic is also used in ProxyExecutionManager.StartTestRun
                    // Differences:
                    // Aborted is sent to allow the current execution manager replaced with another instance
                    // Ensure that the test run aggregator in parallel run events handler doesn't add these statistics
                    // (since the test run didn't even start)
                    var completeArgs = new TestRunCompleteEventArgs(null, false, true, null, new Collection <AttachmentSet>(), TimeSpan.Zero);
                    this.GetHandlerForGivenManager(proxyExecutionManager).HandleTestRunComplete(completeArgs, null, null, null);
                },
                              TaskContinuationOptions.OnlyOnFaulted);
            }

            if (EqtTrace.IsVerboseEnabled)
            {
                EqtTrace.Verbose("ProxyParallelExecutionManager: No sources available for execution.");
            }
        }
Example #23
0
 /// <summary>
 /// Aborts the test run.
 /// </summary>
 public void AbortTestRun()
 {
     EqtTrace.Info("TestRequestManager.AbortTestRun: Sending abort request.");
     this.currentTestRunRequest?.Abort();
 }
Example #24
0
        /// <summary>
        /// Add a new file transfer (either copy/move) request.
        /// </summary>
        /// <param name="fileTransferInfo">
        /// The file Transfer Info.
        /// </param>
        /// <param name="sendFileCompletedCallback">
        /// The send File Completed Callback.
        /// </param>
        /// <param name="uri">
        /// The uri.
        /// </param>
        /// <param name="friendlyName">
        /// The friendly Name.
        /// </param>
        private void AddNewFileTransfer(FileTransferInformation fileTransferInfo, AsyncCompletedEventHandler sendFileCompletedCallback, Uri uri, string friendlyName)
        {
            var context = fileTransferInfo.Context;

            Debug.Assert(
                context != null,
                "DataCollectionManager.AddNewFileTransfer: FileDataHeaderMessage with null context.");

            var testCaseId = fileTransferInfo.Context.HasTestCase
                                 ? fileTransferInfo.Context.TestExecId.Id.ToString()
                                 : string.Empty;

            var directoryPath = Path.Combine(
                this.SessionOutputDirectory,
                testCaseId);
            var localFilePath = Path.Combine(directoryPath, Path.GetFileName(fileTransferInfo.FileName));

            var task = Task.Factory.StartNew(
                () =>
            {
                Validate(fileTransferInfo, localFilePath);

                if (this.cancellationTokenSource.Token.IsCancellationRequested)
                {
                    this.cancellationTokenSource.Token.ThrowIfCancellationRequested();
                }

                try
                {
                    if (fileTransferInfo.PerformCleanup)
                    {
                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("DataCollectionAttachmentManager.AddNewFileTransfer : Moving file {0} to {1}", fileTransferInfo.FileName, localFilePath);
                        }

                        this.fileHelper.MoveFile(fileTransferInfo.FileName, localFilePath);

                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("DataCollectionAttachmentManager.AddNewFileTransfer : Moved file {0} to {1}", fileTransferInfo.FileName, localFilePath);
                        }
                    }
                    else
                    {
                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("DataCollectionAttachmentManager.AddNewFileTransfer : Copying file {0} to {1}", fileTransferInfo.FileName, localFilePath);
                        }

                        this.fileHelper.CopyFile(fileTransferInfo.FileName, localFilePath);

                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("DataCollectionAttachmentManager.AddNewFileTransfer : Copied file {0} to {1}", fileTransferInfo.FileName, localFilePath);
                        }
                    }
                }
                catch (Exception ex)
                {
                    this.LogError(
                        ex.ToString(),
                        uri,
                        friendlyName,
                        Guid.Parse(testCaseId));

                    throw;
                }
            },
                this.cancellationTokenSource.Token);

            var continuationTask = task.ContinueWith(
                (t) =>
            {
                try
                {
                    if (t.Exception == null)
                    {
                        // Uri doesn't recognize file paths in unix. See https://github.com/dotnet/corefx/issues/1745
                        var attachmentUri = new UriBuilder()
                        {
                            Scheme = "file", Host = "", Path = localFilePath
                        }.Uri;
                        lock (attachmentTaskLock)
                        {
                            this.AttachmentSets[fileTransferInfo.Context][uri].Attachments.Add(new UriDataAttachment(attachmentUri, fileTransferInfo.Description));
                        }
                    }

                    if (sendFileCompletedCallback != null)
                    {
                        sendFileCompletedCallback(this, new AsyncCompletedEventArgs(t.Exception, false, fileTransferInfo.UserToken));
                    }
                }
                catch (Exception e)
                {
                    if (EqtTrace.IsErrorEnabled)
                    {
                        EqtTrace.Error(
                            "DataCollectionAttachmentManager.TriggerCallBack: Error occurred while raising the file transfer completed callback for {0}. Error: {1}",
                            localFilePath,
                            e.ToString());
                    }
                }
            },
                this.cancellationTokenSource.Token);

            this.attachmentTasks[fileTransferInfo.Context].Add(continuationTask);
        }
Example #25
0
 /// <inheritdoc />
 public void Close()
 {
     this.Dispose();
     EqtTrace.Info("Closing the connection !");
 }
Example #26
0
        /// <summary>
        /// Called when a test run is completed.
        /// </summary>
        private void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e)
        {
            Output.WriteLine(string.Empty, OutputLevel.Information);

            // Printing Run-level Attachments
            var runLevelAttachementCount = (e.AttachmentSets == null) ? 0 : e.AttachmentSets.Sum(attachmentSet => attachmentSet.Attachments.Count);

            if (runLevelAttachementCount > 0)
            {
                Output.Information(false, CommandLineResources.AttachmentsBanner);
                foreach (var attachmentSet in e.AttachmentSets)
                {
                    foreach (var uriDataAttachment in attachmentSet.Attachments)
                    {
                        var attachmentOutput = string.Format(CultureInfo.CurrentCulture, CommandLineResources.AttachmentOutputFormat, uriDataAttachment.Uri.LocalPath);
                        Output.Information(false, attachmentOutput);
                    }
                }
                Output.WriteLine(String.Empty, OutputLevel.Information);
            }

            // Output a summary.
            if (this.testsTotal > 0)
            {
                string testCountDetails;

                if (e.IsAborted || e.IsCanceled)
                {
                    testCountDetails = string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummaryForCanceledOrAbortedRun, testsPassed, testsFailed, testsSkipped);
                }
                else
                {
                    testCountDetails = string.Format(CultureInfo.CurrentCulture, CommandLineResources.TestRunSummary, testsTotal, testsPassed, testsFailed, testsSkipped);
                }

                Output.Information(false, testCountDetails);
            }

            if (e.IsCanceled)
            {
                Output.Error(false, CommandLineResources.TestRunCanceled);
            }
            else if (e.IsAborted)
            {
                Output.Error(false, CommandLineResources.TestRunAborted);
            }
            else if (this.testOutcome == TestOutcome.Failed && this.testsTotal > 0)
            {
                Output.Error(false, CommandLineResources.TestRunFailed);
            }
            else if (this.testsTotal > 0)
            {
                Output.Information(false, ConsoleColor.Green, CommandLineResources.TestRunSuccessful);
            }

            if (this.testsTotal > 0)
            {
                if (!e.ElapsedTimeInRunningTests.Equals(TimeSpan.Zero))
                {
                    PrintTimeSpan(e.ElapsedTimeInRunningTests);
                }
                else
                {
                    EqtTrace.Info("Skipped printing test execution time on console because it looks like the test run had faced some errors");
                }
            }
        }
Example #27
0
        /// <summary>
        /// Discover Tests given a list of sources, run settings.
        /// </summary>
        /// <param name="discoveryPayload">Discovery payload</param>
        /// <param name="discoveryEventsRegistrar">EventHandler for discovered tests</param>
        /// <param name="protocolConfig">Protocol related information</param>
        /// <returns>True, if successful</returns>
        public bool DiscoverTests(DiscoveryRequestPayload discoveryPayload, ITestDiscoveryEventsRegistrar discoveryEventsRegistrar, ProtocolConfig protocolConfig)
        {
            EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests started.");

            bool success     = false;
            var  runsettings = discoveryPayload.RunSettings;

            if (discoveryPayload.TestPlatformOptions != null)
            {
                this.telemetryOptedIn = discoveryPayload.TestPlatformOptions.CollectMetrics;
            }

            var requestData = this.GetRequestData(protocolConfig);

            if (this.UpdateRunSettingsIfRequired(runsettings, discoveryPayload.Sources?.ToList(), out string updatedRunsettings))
            {
                runsettings = updatedRunsettings;
            }

            var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettings);
            var batchSize        = runConfiguration.BatchSize;

            if (requestData.IsTelemetryOptedIn)
            {
                // Collect Metrics
                this.CollectMetrics(requestData, runConfiguration);

                // Collect Commands
                this.LogCommandsTelemetryPoints(requestData);
            }

            // create discovery request
            var criteria = new DiscoveryCriteria(discoveryPayload.Sources, batchSize, this.commandLineOptions.TestStatsEventTimeout, runsettings);

            criteria.TestCaseFilter = this.commandLineOptions.TestCaseFilterValue;

            try
            {
                using (IDiscoveryRequest discoveryRequest = this.testPlatform.CreateDiscoveryRequest(requestData, criteria))
                {
                    try
                    {
                        this.testLoggerManager?.RegisterDiscoveryEvents(discoveryRequest);
                        discoveryEventsRegistrar?.RegisterDiscoveryEvents(discoveryRequest);

                        this.testPlatformEventSource.DiscoveryRequestStart();

                        discoveryRequest.DiscoverAsync();
                        discoveryRequest.WaitForCompletion();

                        success = true;
                    }

                    finally
                    {
                        this.testLoggerManager?.UnregisterDiscoveryEvents(discoveryRequest);
                        discoveryEventsRegistrar?.UnregisterDiscoveryEvents(discoveryRequest);
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is TestPlatformException ||
                    ex is SettingsException ||
                    ex is InvalidOperationException)
                {
                    LoggerUtilities.RaiseTestRunError(testLoggerManager, null, ex);
                    success = false;
                }
                else
                {
                    throw;
                }
            }

            EqtTrace.Info("TestRequestManager.DiscoverTests: Discovery tests completed, successful: {0}.", success);
            this.testPlatformEventSource.DiscoveryRequestStop();

            // Posts the Discovery Complete event.
            this.metricsPublisher.Result.PublishMetrics(TelemetryDataConstants.TestDiscoveryCompleteEvent, requestData.MetricsCollection.Metrics);

            return(success);
        }
Example #28
0
        /// <summary>
        /// Execute the test run asynchronously
        /// </summary>
        /// <returns>The process id of test host.</returns>
        public int ExecuteAsync()
        {
            EqtTrace.Verbose("TestRunRequest.ExecuteAsync: Starting.");

            lock (this.syncObject)
            {
                if (this.disposed)
                {
                    throw new ObjectDisposedException("testRunRequest");
                }

                if (this.State != TestRunState.Pending)
                {
                    throw new InvalidOperationException(ClientResources.InvalidStateForExecution);
                }

                this.executionStartTime = DateTime.UtcNow;

                // Collecting Number of sources Sent For Execution
                var numberOfSources = (uint)(testRunCriteria.Sources != null ? testRunCriteria.Sources.Count <string>() : 0);
                this.requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfSourcesSentForRun, numberOfSources);

                if (EqtTrace.IsInfoEnabled)
                {
                    EqtTrace.Info("TestRunRequest.ExecuteAsync: Starting run with settings:{0}", this.testRunCriteria);
                }

                if (EqtTrace.IsVerboseEnabled)
                {
                    // Waiting for warm up to be over.
                    EqtTrace.Verbose("TestRunRequest.ExecuteAsync: Wait for the first run request is over.");
                }

                this.State = TestRunState.InProgress;

                // Reset the run completion event
                // (This needs to be done before queuing the test run because if the test run finishes fast then runCompletion event can
                // remain in non-signaled state even though run is actually complete.
                this.runCompletionEvent.Reset();

                try
                {
                    var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(this.TestRunCriteria.TestRunSettings);
                    this.testSessionTimeout = runConfiguration.TestSessionTimeout;

                    if (testSessionTimeout > 0)
                    {
                        if (EqtTrace.IsVerboseEnabled)
                        {
                            EqtTrace.Verbose(String.Format("TestRunRequest.ExecuteAsync: TestSessionTimeout is {0} milliseconds.", testSessionTimeout));
                        }

                        this.timer = new Timer(this.OnTestSessionTimeout, null, TimeSpan.FromMilliseconds(testSessionTimeout), TimeSpan.FromMilliseconds(0));
                    }

                    this.runRequestTimeTracker = new Stopwatch();

                    // Start the stop watch for calculating the test run time taken overall
                    this.runRequestTimeTracker.Start();
                    var testRunStartEvent = new TestRunStartEventArgs(this.testRunCriteria);
                    this.LoggerManager.HandleTestRunStart(testRunStartEvent);
                    this.OnRunStart.SafeInvoke(this, testRunStartEvent, "TestRun.TestRunStart");
                    int processId = this.ExecutionManager.StartTestRun(this.testRunCriteria, this);

                    if (EqtTrace.IsInfoEnabled)
                    {
                        EqtTrace.Info("TestRunRequest.ExecuteAsync: Started.");
                    }

                    return(processId);
                }
                catch
                {
                    this.State = TestRunState.Pending;
                    throw;
                }
            }
        }
Example #29
0
        private bool UpdateRunSettingsIfRequired(string runsettingsXml, List <string> sources, out string updatedRunSettingsXml)
        {
            bool settingsUpdated = false;

            updatedRunSettingsXml = runsettingsXml;
            IDictionary <string, Architecture> sourcePlatforms  = new Dictionary <string, Architecture>();
            IDictionary <string, Framework>    sourceFrameworks = new Dictionary <string, Framework>();

            if (!string.IsNullOrEmpty(runsettingsXml))
            {
                // TargetFramework is full CLR. Set DesignMode based on current context.
                using (var stream = new StringReader(runsettingsXml))
                    using (var reader = XmlReader.Create(stream, XmlRunSettingsUtilities.ReaderSettings))
                    {
                        var document = new XmlDocument();
                        document.Load(reader);

                        var navigator = document.CreateNavigator();

                        var          inferedFramework = inferHelper.AutoDetectFramework(sources, sourceFrameworks);
                        Framework    chosenFramework;
                        var          inferedPlatform = inferHelper.AutoDetectArchitecture(sources, sourcePlatforms);
                        Architecture chosenPlatform;

                        // Update frmaework and platform if required. For commandline scenario update happens in ArgumentProcessor.
                        bool updateFramework = IsAutoFrameworkDetectRequired(navigator, out chosenFramework);
                        bool updatePlatform  = IsAutoPlatformDetectRequired(navigator, out chosenPlatform);

                        if (updateFramework)
                        {
                            InferRunSettingsHelper.UpdateTargetFramework(document, inferedFramework?.ToString(), overwrite: true);
                            chosenFramework = inferedFramework;
                            settingsUpdated = true;
                        }

                        if (updatePlatform)
                        {
                            InferRunSettingsHelper.UpdateTargetPlatform(document, inferedPlatform.ToString(), overwrite: true);
                            chosenPlatform  = inferedPlatform;
                            settingsUpdated = true;
                        }

                        var compatibleSources = InferRunSettingsHelper.FilterCompatibleSources(chosenPlatform, chosenFramework, sourcePlatforms, sourceFrameworks, out var incompatibleSettingWarning);

                        if (!string.IsNullOrEmpty(incompatibleSettingWarning))
                        {
                            EqtTrace.Info(incompatibleSettingWarning);
                            LoggerUtilities.RaiseTestRunWarning(this.testLoggerManager, this.testRunResultAggregator, incompatibleSettingWarning);
                        }

                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("Compatible sources list : ");
                            EqtTrace.Info(string.Join("\n", compatibleSources.ToArray()));
                        }

                        // If user is already setting DesignMode via runsettings or CLI args; we skip.
                        var runConfiguration = XmlRunSettingsUtilities.GetRunConfigurationNode(runsettingsXml);

                        if (!runConfiguration.DesignModeSet)
                        {
                            InferRunSettingsHelper.UpdateDesignMode(document, this.commandLineOptions.IsDesignMode);
                            settingsUpdated = true;
                        }

                        if (!runConfiguration.CollectSourceInformationSet)
                        {
                            InferRunSettingsHelper.UpdateCollectSourceInformation(document, this.commandLineOptions.ShouldCollectSourceInformation);
                            settingsUpdated = true;
                        }

                        if (InferRunSettingsHelper.TryGetDeviceXml(navigator, out string deviceXml))
                        {
                            InferRunSettingsHelper.UpdateTargetDevice(document, deviceXml);
                            settingsUpdated = true;
                        }

                        updatedRunSettingsXml = navigator.OuterXml;
                    }
            }

            return(settingsUpdated);
        }
Example #30
0
        private async Task SendMessageAndListenAndReportTestResultsAsync(string messageType, object payload, ITestRunEventsHandler eventHandler, ITestHostLauncher customHostLauncher)
        {
            try
            {
                this.communicationManager.SendMessage(messageType, payload, this.protocolVersion);
                var isTestRunComplete = 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 (!isTestRunComplete)
                {
                    var message = await this.TryReceiveMessageAsync();

                    if (string.Equals(MessageType.TestRunStatsChange, message.MessageType))
                    {
                        var testRunChangedArgs = this.dataSerializer.DeserializePayload <TestRunChangedEventArgs>(
                            message);
                        eventHandler.HandleTestRunStatsChange(testRunChangedArgs);
                    }
                    else if (string.Equals(MessageType.ExecutionComplete, message.MessageType))
                    {
                        if (EqtTrace.IsInfoEnabled)
                        {
                            EqtTrace.Info("VsTestConsoleRequestSender.SendMessageAndListenAndReportTestResultsAsync: Execution complete.");
                        }

                        var testRunCompletePayload =
                            this.dataSerializer.DeserializePayload <TestRunCompletePayload>(message);

                        eventHandler.HandleTestRunComplete(
                            testRunCompletePayload.TestRunCompleteArgs,
                            testRunCompletePayload.LastRunTests,
                            testRunCompletePayload.RunAttachments,
                            testRunCompletePayload.ExecutorUris);
                        isTestRunComplete = true;
                    }
                    else if (string.Equals(MessageType.TestMessage, message.MessageType))
                    {
                        var testMessagePayload = this.dataSerializer.DeserializePayload <TestMessagePayload>(message);
                        eventHandler.HandleLogMessage(testMessagePayload.MessageLevel, testMessagePayload.Message);
                    }
                    else if (string.Equals(MessageType.CustomTestHostLaunch, message.MessageType))
                    {
                        HandleCustomHostLaunch(customHostLauncher, message);
                    }
                    else if (string.Equals(MessageType.EditorAttachDebugger, message.MessageType))
                    {
                        AttachDebuggerToProcess(customHostLauncher, message);
                    }
                }
            }
            catch (Exception exception)
            {
                EqtTrace.Error("Aborting Test Run Operation: {0}", exception);
                eventHandler.HandleLogMessage(TestMessageLevel.Error, TranslationLayerResources.AbortedTestsRun);
                var completeArgs = new TestRunCompleteEventArgs(null, false, true, exception, null, TimeSpan.Zero);
                eventHandler.HandleTestRunComplete(completeArgs, null, null, null);

                // Earlier we were closing the connection with vstest.console in case of exceptions
                // Removing that code because vstest.console might be in a healthy state and letting the client
                // know of the error, so that the TL can wait for the next instruction from the client itself.
                // Also, connection termination might not kill the process which could result in files being locked by testhost.
            }

            this.testPlatformEventSource.TranslationLayerExecutionStop();
        }