private bool RunTestInternalWithExecutors()

in src/Microsoft.TestPlatform.CrossPlatEngine/Execution/BaseRunTests.cs [376:575]


    private bool RunTestInternalWithExecutors(IEnumerable<Tuple<Uri, string>> executorUriExtensionMap, long totalTests)
    {
        // Collecting Total Number of Adapters Discovered in Machine.
        _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 = 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 = " ";
                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 (!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)
                || ShouldAttachDebuggerToTestHost(executor, executorUriExtensionTuple, RunContext))
            {
                EqtTrace.Verbose("Attaching to default test host.");

                attachedToTestHost = true;
                var pid = Process.GetCurrentProcess().Id;
                if (!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
                _activeExecutor = executor.Value;

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

                var timeStartNow = DateTime.UtcNow;

                var currentTotalTests = TestRunCache.TotalExecutedTests;
                _testPlatformEventSource.AdapterExecutionStart(executorUri);

                // Run the tests.
                if (NotRequiredStaThread() || !TryToRunInStaThread(() => InvokeExecutor(executor, executorUriExtensionTuple, RunContext, FrameworkHandle), true))
                {
                    InvokeExecutor(executor, executorUriExtensionTuple, RunContext, FrameworkHandle);
                }

                _testPlatformEventSource.AdapterExecutionStop(TestRunCache.TotalExecutedTests - currentTotalTests);

                var totalTimeTaken = DateTime.UtcNow - timeStartNow;

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

                    // Collecting Total Tests Ran by each Adapter
                    var totalTestRun = TestRunCache.TotalExecutedTests - totalTests;
                    _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 TestRunCache.AdapterTelemetry.Keys.Where(k => k.StartsWith(executorUri)))
                        {
                            var value = TestRunCache.AdapterTelemetry[adapterMetrics];

                            _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 = TestRunCache.TotalExecutedTests;
                }

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

                // Collecting Time Taken by each executor Uri
                _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);
                }

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

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

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

        return exceptionsHitDuringRunTests;
    }