Esempio n. 1
0
        /// <summary>
        /// Notifies the cache of a new test result from the adapter.
        /// </summary>
        /// <param name="testResult"> The test result. </param>
        public void OnNewTestResult(TestResult testResult)
        {
            lock (this.syncObject)
            {
                this.totalExecutedTests++;
                this.testResults.Add(testResult);
                MSTestV1TelemetryHelper.AddTelemetry(testResult, this.AdapterTelemetry);

                long count;
                if (this.runStats.TryGetValue(testResult.Outcome, out count))
                {
                    count++;
                }
                else
                {
                    count = 1;
                }

                this.runStats[testResult.Outcome] = count;

                this.RemoveInProgress(testResult);

                this.CheckForCacheHit();
            }
        }
Esempio n. 2
0
        private bool RunTestInternalWithExecutors(IEnumerable <Tuple <Uri, string> > executorUriExtensionMap, long totalTests)
        {
            // Collecting Total Number of Adapters Discovered in Machine.
            this.requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfAdapterDiscoveredDuringExecution, executorUriExtensionMap.Count());

            var attachedToTestHost = false;
            var executorCache      = new Dictionary <string, LazyExtension <ITestExecutor, ITestExecutorCapabilities> >();

            foreach (var executorUriExtensionTuple in executorUriExtensionMap)
            {
                // Avoid processing the same executor twice.
                if (executorCache.ContainsKey(executorUriExtensionTuple.Item1.AbsoluteUri))
                {
                    continue;
                }

                // Get the extension manager.
                var extensionManager = this.GetExecutorExtensionManager(executorUriExtensionTuple.Item2);

                // Look up the executor.
                var executor = extensionManager.TryGetTestExtension(executorUriExtensionTuple.Item1);
                if (executor == null)
                {
                    // Commenting this out because of a compatibility issue with Microsoft.Dotnet.ProjectModel released on nuGet.org.
                    // this.activeExecutor = null;
                    // var runtimeVersion = string.Concat(PlatformServices.Default.Runtime.RuntimeType, " ",
                    // PlatformServices.Default.Runtime.RuntimeVersion);
                    var runtimeVersion = " ";
                    this.TestRunEventsHandler?.HandleLogMessage(
                        TestMessageLevel.Warning,
                        string.Format(
                            CultureInfo.CurrentUICulture,
                            CrossPlatEngineResources.NoMatchingExecutor,
                            executorUriExtensionTuple.Item1.AbsoluteUri,
                            runtimeVersion));

                    continue;
                }

                // Cache the executor.
                executorCache.Add(executorUriExtensionTuple.Item1.AbsoluteUri, executor);

                // Check if we actually have to attach to the default test host.
                if (!this.runContext.IsBeingDebugged || attachedToTestHost)
                {
                    // We already know we should attach to the default test host, simply continue.
                    continue;
                }

                // If there's at least one adapter in the filtered adapters list that doesn't
                // implement the new test executor interface, we should attach to the default test
                // host by default.
                // Same goes if all adapters implement the new test executor interface but at
                // least one of them needs the test platform to attach to the default test host.
                if (!(executor.Value is ITestExecutor2) ||
                    this.ShouldAttachDebuggerToTestHost(executor, executorUriExtensionTuple, this.runContext))
                {
                    EqtTrace.Verbose("Attaching to default test host.");

                    attachedToTestHost = true;
                    var pid = Process.GetCurrentProcess().Id;
                    if (!this.frameworkHandle.AttachDebuggerToProcess(pid))
                    {
                        EqtTrace.Warning(
                            string.Format(
                                CultureInfo.CurrentUICulture,
                                CrossPlatEngineResources.AttachDebuggerToDefaultTestHostFailure,
                                pid));
                    }
                }
            }


            // Call the executor for each group of tests.
            var    exceptionsHitDuringRunTests      = false;
            var    executorsFromDeprecatedLocations = false;
            double totalTimeTakenByAdapters         = 0;

            foreach (var executorUriExtensionTuple in executorUriExtensionMap)
            {
                var executorUri = executorUriExtensionTuple.Item1.AbsoluteUri;
                // Get the executor from the cache.
                if (!executorCache.TryGetValue(executorUri, out var executor))
                {
                    continue;
                }

                try
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose(
                            "BaseRunTests.RunTestInternalWithExecutors: Running tests for {0}",
                            executor.Metadata.ExtensionUri);
                    }

                    // set the active executor
                    this.activeExecutor = executor.Value;

                    // If test run cancellation is requested, skip the next executor
                    if (this.isCancellationRequested)
                    {
                        break;
                    }

                    var timeStartNow = DateTime.UtcNow;

                    var currentTotalTests = this.testRunCache.TotalExecutedTests;
                    this.testPlatformEventSource.AdapterExecutionStart(executorUri);

                    // Run the tests.
                    if (this.NotRequiredSTAThread() || !this.TryToRunInSTAThread(() => this.InvokeExecutor(executor, executorUriExtensionTuple, this.runContext, this.frameworkHandle), true))
                    {
                        this.InvokeExecutor(executor, executorUriExtensionTuple, this.runContext, this.frameworkHandle);
                    }

                    this.testPlatformEventSource.AdapterExecutionStop(this.testRunCache.TotalExecutedTests - currentTotalTests);

                    var totalTimeTaken = DateTime.UtcNow - timeStartNow;

                    // Identify whether the executor did run any tests at all
                    if (this.testRunCache.TotalExecutedTests > totalTests)
                    {
                        this.executorUrisThatRanTests.Add(executorUri);

                        // Collecting Total Tests Ran by each Adapter
                        var totalTestRun = this.testRunCache.TotalExecutedTests - totalTests;
                        this.requestData.MetricsCollection.Add(string.Format("{0}.{1}", TelemetryDataConstants.TotalTestsRanByAdapter, executorUri), totalTestRun);

                        // Only enable this for MSTestV1 telemetry for now, this might become more generic later.
                        if (MSTestV1TelemetryHelper.IsMSTestV1Adapter(executorUri))
                        {
                            foreach (var adapterMetrics in this.testRunCache.AdapterTelemetry.Keys.Where(k => k.StartsWith(executorUri)))
                            {
                                var value = this.testRunCache.AdapterTelemetry[adapterMetrics];

                                this.requestData.MetricsCollection.Add(string.Format("{0}.{1}", TelemetryDataConstants.TotalTestsRunByMSTestv1, adapterMetrics), value);
                            }
                        }

                        if (!CrossPlatEngine.Constants.DefaultAdapters.Contains(executor.Metadata.ExtensionUri, StringComparer.OrdinalIgnoreCase))
                        {
                            var executorLocation = executor.Value.GetType().GetTypeInfo().Assembly.GetAssemblyLocation();

                            executorsFromDeprecatedLocations |= Path.GetDirectoryName(executorLocation).Equals(CrossPlatEngine.Constants.DefaultAdapterLocation);
                        }

                        totalTests = this.testRunCache.TotalExecutedTests;
                    }

                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose(
                            "BaseRunTests.RunTestInternalWithExecutors: Completed running tests for {0}",
                            executor.Metadata.ExtensionUri);
                    }

                    // Collecting Time Taken by each executor Uri
                    this.requestData.MetricsCollection.Add(string.Format("{0}.{1}", TelemetryDataConstants.TimeTakenToRunTestsByAnAdapter, executorUri), totalTimeTaken.TotalSeconds);
                    totalTimeTakenByAdapters += totalTimeTaken.TotalSeconds;
                }
                catch (Exception e)
                {
                    string exceptionMessage = (e is UnauthorizedAccessException)
                            ? string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.AccessDenied, e.Message)
                            : ExceptionUtilities.GetExceptionMessage(e);

                    exceptionsHitDuringRunTests = true;

                    if (EqtTrace.IsErrorEnabled)
                    {
                        EqtTrace.Error(
                            "BaseRunTests.RunTestInternalWithExecutors: An exception occurred while invoking executor {0}. {1}.",
                            executorUriExtensionTuple.Item1,
                            e);
                    }

                    this.TestRunEventsHandler?.HandleLogMessage(
                        TestMessageLevel.Error,
                        string.Format(
                            CultureInfo.CurrentCulture,
                            CrossPlatEngineResources.ExceptionFromRunTests,
                            executorUriExtensionTuple.Item1,
                            exceptionMessage));
                }
                finally
                {
                    this.activeExecutor = null;
                }
            }

            // Collecting Total Time Taken by Adapters
            this.requestData.MetricsCollection.Add(TelemetryDataConstants.TimeTakenByAllAdaptersInSec, totalTimeTakenByAdapters);

            if (executorsFromDeprecatedLocations)
            {
                this.TestRunEventsHandler?.HandleLogMessage(TestMessageLevel.Warning, string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.DeprecatedAdapterPath));
            }

            return(exceptionsHitDuringRunTests);
        }