Beispiel #1
0
        private void OnProjectLoaded(object sender, ProjectEventArgs e)
        {
            if (e.Project != null)
            {
                string root = null;
                try
                {
                    root = e.Project.GetProjectHome();
                }
                catch (Exception ex)
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Warning("TestContainerDiscoverer: Failed to get project home {0}", ex);
                    }
                    // If we fail to get ProjectHome, we still want to track the
                    // project. We just won't get the benefits of merging
                    // watchers into a single recursive watcher.
                }

                if (e.Project.TryGetProjectPath(out var path) && !this.knownProjects.ContainsKey(path))
                {
                    var dteProject = ((IVsHierarchy)e.Project).GetProject();

                    var projectInfo = new ProjectInfo(
                        e.Project,
                        discoverer: this
                        );

                    this.knownProjects.Add(path, projectInfo);

                    foreach (var p in e.Project.GetProjectItemPaths())
                    {
                        if (!string.IsNullOrEmpty(root) && CommonUtils.IsSubpathOf(root, p))
                        {
                            this.testFilesUpdateWatcher.AddFolderWatch(root);
                            this.fileRootMap[p] = root;
                        }
                        else
                        {
                            this.testFilesUpdateWatcher.AddFileWatch(p);
                        }
                    }
                }
            }

            this.OnTestContainersChanged(e.Project);
        }
        private void DiscoverTestsPrivate(ITestDiscoveryEventsHandler2 discoveryEventsHandler)
        {
            this.currentDiscoveryEventsHandler = discoveryEventsHandler;

            // Cleanup Task for cleaning up the parallel executors except for the default one
            // We do not do this in Sync so that this task does not add up to discovery time
            if (this.lastParallelDiscoveryCleanUpTask != null)
            {
                try
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose("ProxyParallelDiscoveryManager: Wait for last cleanup to complete.");
                    }

                    this.lastParallelDiscoveryCleanUpTask.Wait();
                }
                catch (Exception ex)
                {
                    // if there is an exception disposing off concurrent hosts ignore it
                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning("ParallelProxyDiscoveryManager: Exception while invoking an action on DiscoveryManager: {0}", ex);
                    }
                }

                this.lastParallelDiscoveryCleanUpTask = null;
            }

            // Reset the discoverycomplete data
            this.discoveryCompletedClients = 0;

            // One data aggregator per parallel discovery
            this.currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator();

            foreach (var concurrentManager in this.GetConcurrentManagerInstances())
            {
                var parallelEventsHandler = new ParallelDiscoveryEventsHandler(
                    this.requestData,
                    concurrentManager,
                    discoveryEventsHandler,
                    this,
                    this.currentDiscoveryDataAggregator);

                this.UpdateHandlerForManager(concurrentManager, parallelEventsHandler);
                this.DiscoverTestsOnConcurrentManager(concurrentManager);
            }
        }
Beispiel #3
0
 private void TestSessionMessageHandler(object sender, TestRunMessageEventArgs e)
 {
     if (this.testMessageEventsHandler != null)
     {
         this.testMessageEventsHandler.HandleLogMessage(e.Level, e.Message);
     }
     else
     {
         if (EqtTrace.IsWarningEnabled)
         {
             EqtTrace.Warning(
                 "ExecutionManager: Could not pass the log message  '{0}' as the callback is null.",
                 e.Message);
         }
     }
 }
Beispiel #4
0
        private void OnReportTestCases(IEnumerable <TestCase> testCases)
        {
            UpdateTestCases(testCases, this.discoveryCriteria.Package);

            if (this.testDiscoveryEventsHandler != null)
            {
                this.testDiscoveryEventsHandler.HandleDiscoveredTests(testCases);
            }
            else
            {
                if (EqtTrace.IsWarningEnabled)
                {
                    EqtTrace.Warning("DiscoveryManager: Could not pass the test results as the callback is null.");
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Dispose the Telemetry Session
        /// </summary>
        public void Dispose()
        {
#if NET451
            try
            {
                this.session.Dispose();
            }
            catch (Exception e)
            {
                if (EqtTrace.IsWarningEnabled)
                {
                    EqtTrace.Warning(string.Format(CultureInfo.InvariantCulture, "TelemetrySession: Error in Disposing Event: {0}", e.Message));
                }
            }
#endif
        }
Beispiel #6
0
        /// <summary>
        /// Handler for vanguard process exit event
        /// </summary>
        /// <param name="sender">The sender. </param>
        /// <param name="e">Event args. </param>
        private void LoggerProcessExited(object sender, EventArgs e)
        {
            EqtTrace.Info("Vanguard.LoggerProcessExited: Vanguard process exit callback started.");
            if (this.vanguardProcess != null)
            {
                if (this.vanguardProcess.HasExited == true && this.vanguardProcess.ExitCode != 0)
                {
                    EqtTrace.Warning("Vanguard.LoggerProcessExited: An error occurred in Code Coverage process. Error code = {0}", this.vanguardProcess.ExitCode);
                }

                this.vanguardProcess.Exited            -= this.LoggerProcessExited;
                this.vanguardProcess.ErrorDataReceived -= this.LoggerProcessErrorDataReceived;

                this.vanguardProcessExitEvent.Set();
            }
        }
        private int StartTestRunPrivate(ITestRunEventsHandler runEventsHandler)
        {
            this.currentRunEventsHandler = runEventsHandler;

            // Cleanup Task for cleaning up the parallel executors except for the default one
            // We do not do this in Sync so that this task does not add up to execution time
            if (this.lastParallelRunCleanUpTask != null)
            {
                try
                {
                    this.lastParallelRunCleanUpTask.Wait();
                }
                catch (Exception ex)
                {
                    // if there is an exception disposing off concurrent executors ignore it
                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning("ParallelTestRunnerServiceClient: Exception while invoking an action on DiscoveryManager: {0}", ex);
                    }
                }

                this.lastParallelRunCleanUpTask = null;
            }

            // Reset the runcomplete data
            this.runCompletedClients = 0;

            // One data aggregator per parallel run
            this.currentRunDataAggregator    = new ParallelRunDataAggregator();
            this.concurrentManagerHandlerMap = new Dictionary <IProxyExecutionManager, ITestRunEventsHandler>();

            for (int i = 0; i < this.concurrentManagerInstances.Length; i++)
            {
                var concurrentManager = this.concurrentManagerInstances[i];

                var parallelEventsHandler = new ParallelRunEventsHandler(
                    concurrentManager,
                    runEventsHandler,
                    this,
                    this.currentRunDataAggregator);
                this.concurrentManagerHandlerMap.Add(concurrentManager, parallelEventsHandler);

                Task.Run(() => this.StartTestRunOnConcurrentManager(concurrentManager));
            }

            return(1);
        }
Beispiel #8
0
        /// <summary>
        /// Called when Session End event is invoked
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="args">SessionEndEventArgs</param>
        private void SessionEnded_Handler(object sender, SessionEndEventArgs args)
        {
            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("Blame Collector : Session End");
            }

            // 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.processDumpEnabled)
            {
                // 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.SessionEnded_Handler: blame:CollectDump was enabled but dump file was not generated.");
                            this.logger.LogWarning(args.Context, Resources.Resources.ProcDumpNotGenerated);
                        }
                    }
                    catch (FileNotFoundException ex)
                    {
                        EqtTrace.Warning(ex.Message);
                        this.logger.LogWarning(args.Context, ex.Message);
                    }
                }
            }

            this.DeregisterEvents();
        }
Beispiel #9
0
        /// <summary>
        /// Gets test extensions from a given assembly.
        /// </summary>
        /// <param name="assembly">Assembly to check for test extension availability</param>
        /// <param name="testDiscoverers">Test discoverers collection to add to.</param>
        /// <param name="testExecutors">Test executors collection to add to.</param>
        /// <param name="testSettingsProviders">Test settings providers collection to add to.</param>
        /// <param name="testLoggers">Test loggers collection to add to.</param>
        private void GetTestExtensionsFromAssembly(
            Assembly assembly,
            Dictionary <string, TestDiscovererPluginInformation> testDiscoverers,
            Dictionary <string, TestExecutorPluginInformation> testExecutors,
            Dictionary <string, TestSettingsProviderPluginInformation> testSettingsProviders,
            Dictionary <string, TestLoggerPluginInformation> testLoggers)
        {
            Debug.Assert(assembly != null, "null assembly");
            Debug.Assert(testDiscoverers != null, "null testDiscoverers");
            Debug.Assert(testExecutors != null, "null testExecutors");
            Debug.Assert(testSettingsProviders != null, "null testSettingsProviders");
            Debug.Assert(testLoggers != null, "null testLoggers");

            Type[] types = null;
            try
            {
                types = assembly.GetTypes();
            }
            catch (ReflectionTypeLoadException e)
            {
                EqtTrace.Warning("TestPluginDiscoverer: Failed to get types from assembly '{0}'.  Skipping test extension scan for this assembly.  Error: {1}", assembly.FullName, e.ToString());

                if (e.LoaderExceptions != null)
                {
                    foreach (var ex in e.LoaderExceptions)
                    {
                        EqtTrace.Warning("LoaderExceptions: {0}", ex);
                    }
                }

                return;
            }

            if ((types != null) && (types.Length > 0))
            {
                foreach (var type in types)
                {
                    if (type.GetTypeInfo().IsClass&& !type.GetTypeInfo().IsAbstract)
                    {
                        this.GetTestExtensionFromType <TestDiscovererPluginInformation>(type, typeof(ITestDiscoverer), testDiscoverers);
                        this.GetTestExtensionFromType <TestExecutorPluginInformation>(type, typeof(ITestExecutor), testExecutors);
                        this.GetTestExtensionFromType <TestLoggerPluginInformation>(type, typeof(ITestLogger), testLoggers);
                        this.GetTestExtensionFromType <TestSettingsProviderPluginInformation>(type, typeof(ISettingsProvider), testSettingsProviders);
                    }
                }
            }
        }
Beispiel #10
0
        /// <summary>
        /// Called when a test message is received.
        /// </summary>
        private void TestMessageHandler(object sender, TestRunMessageEventArgs e)
        {
            ValidateArg.NotNull <object>(sender, "sender");
            ValidateArg.NotNull <TestRunMessageEventArgs>(e, "e");

            // Pause the progress indicator to print the message
            this.progressIndicator?.Pause();

            switch (e.Level)
            {
            case TestMessageLevel.Informational:
            {
                if (verbosityLevel == Verbosity.Quiet || verbosityLevel == Verbosity.Minimal)
                {
                    break;
                }

                Output.Information(AppendPrefix, e.Message);
                break;
            }

            case TestMessageLevel.Warning:
            {
                if (verbosityLevel == Verbosity.Quiet)
                {
                    break;
                }

                Output.Warning(AppendPrefix, e.Message);
                break;
            }

            case TestMessageLevel.Error:
            {
                this.testRunHasErrorMessages = true;
                Output.Error(AppendPrefix, e.Message);
                break;
            }

            default:
                EqtTrace.Warning("ConsoleLogger.TestMessageHandler: The test message level is unrecognized: {0}", e.Level.ToString());
                break;
            }

            // Resume the progress indicator after printing the message
            this.progressIndicator?.Start();
        }
Beispiel #11
0
        /// <inheritdoc />
        public void StartTestRun(TestRunCriteriaWithTests runCriteria, ITestRunEventsHandler eventHandler)
        {
            this.messageEventHandler = eventHandler;
            this.onDisconnected      = (disconnectedEventArgs) =>
            {
                this.OnTestRunAbort(eventHandler, disconnectedEventArgs.Error, true);
            };

            this.onMessageReceived        = (sender, args) => this.OnExecutionMessageReceived(sender, args, eventHandler);
            this.channel.MessageReceived += this.onMessageReceived;

            // This code section is needed because we altered the old testhost launch process for
            // the debugging workflow. Now we don't ask VS to launch and attach to the testhost
            // process for us as we previously did, instead we launch it as a standalone process
            // and rely on the testhost to ask VS to attach the debugger to itself.
            //
            // In order to avoid breaking compatibility with previous testhost versions because of
            // those changes (older testhosts won't know to request VS to attach to themselves
            // thinking instead VS launched and attached to them already), we request VS to attach
            // to the testhost here before starting the test run.
            if (runCriteria.TestExecutionContext != null &&
                runCriteria.TestExecutionContext.IsDebug &&
                this.runtimeProvider is ITestRuntimeProvider2 convertedRuntimeProvider &&
                this.protocolVersion < ObjectModelConstants.MinimumProtocolVersionWithDebugSupport)
            {
                var handler = (ITestRunEventsHandler2)eventHandler;
                if (!convertedRuntimeProvider.AttachDebuggerToTestHost())
                {
                    EqtTrace.Warning(
                        string.Format(
                            CultureInfo.CurrentUICulture,
                            CommonResources.AttachDebuggerToDefaultTestHostFailure));
                }
            }

            var message = this.dataSerializer.SerializePayload(
                MessageType.StartTestExecutionWithTests,
                runCriteria,
                this.protocolVersion);

            if (EqtTrace.IsVerboseEnabled)
            {
                EqtTrace.Verbose("TestRequestSender.StartTestRun: Sending test run with message: {0}", message);
            }

            this.channel.Send(message);
        }
Beispiel #12
0
        private void GetTestExtensionsFromFiles <TPluginInfo, TExtension>(
            string[] files,
            bool loadOnlyWellKnownExtensions,
            Dictionary <string, TPluginInfo> pluginInfos) where TPluginInfo : TestPluginInformation
        {
            Debug.Assert(files != null, "null files");
            Debug.Assert(pluginInfos != null, "null pluginInfos");

            // TODO: Do not see why loadOnlyWellKnowExtensions is still needed.
            //AssemblyName executingAssemblyName = null;
            //if (loadOnlyWellKnownExtensions)
            //{
            //    executingAssemblyName = new AssemblyName(typeof(TestPluginDiscoverer).GetTypeInfo().Assembly.FullName);
            //}

            // Scan each of the files for data extensions.
            foreach (var file in files)
            {
                Assembly assembly = null;
                try
                {
                    var assemblyName = Path.GetFileNameWithoutExtension(file);
                    assembly = Assembly.Load(new AssemblyName(assemblyName));

                    // Check whether this assembly is known or not.
                    //if (loadOnlyWellKnownExtensions && assembly != null)
                    //{
                    //    var extensionAssemblyName = new AssemblyName(assembly.FullName);
                    //    if (!AssemblyUtilities.PublicKeyTokenMatches(extensionAssemblyName, executingAssemblyName))
                    //    {
                    //        EqtTrace.Warning("TestPluginDiscoverer: Ignoring extensions in assembly {0} as it is not a known assembly.", assembly.FullName);
                    //        continue;
                    //    }
                    //}
                }
                catch (Exception e)
                {
                    EqtTrace.Warning("TestPluginDiscoverer: Failed to load file '{0}'.  Skipping test extension scan for this file.  Error: {1}", file, e.ToString());
                    continue;
                }

                if (assembly != null)
                {
                    this.GetTestExtensionsFromAssembly <TPluginInfo, TExtension>(assembly, pluginInfos);
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// Resets the inactivity timer
        /// </summary>
        private void ResetInactivityTimer()
        {
            if (!this.collectProcessDumpOnTestHostHang || this.inactivityTimerAlreadyFired)
            {
                return;
            }

            EqtTrace.Verbose("Reset the inactivity timer since an event was received.");
            try
            {
                this.inactivityTimer.ResetTimer(this.inactivityTimespan);
            }
            catch (Exception e)
            {
                EqtTrace.Warning($"Failed to reset the inactivity timer with error {e}");
            }
        }
Beispiel #14
0
 private void DoManagerAction(Action action)
 {
     try
     {
         action();
     }
     catch (Exception ex)
     {
         // Exception can occur if we are trying to cancel a test run on an executor where test run is not even fired
         // we can safely ignore that as user is just cancelling the test run and we don't care about additional parallel executors
         // as we will be disposing them off soon ansyway
         if (EqtTrace.IsWarningEnabled)
         {
             EqtTrace.Warning("AbstractParallelOperationManager: Exception while invoking an action on Proxy Manager instance: {0}", ex);
         }
     }
 }
Beispiel #15
0
        /// <summary>
        /// Triggers the discovery for the next data object on the concurrent discoverer
        /// Each concurrent discoverer calls this method, once its completed working on previous data
        /// </summary>
        /// <param name="ProxyDiscoveryManager">Proxy discovery manager instance.</param>
        private void DiscoverTestsOnConcurrentManager(IProxyDiscoveryManager proxyDiscoveryManager)
        {
            // Peek to see if we have sources to trigger a discovery
            if (this.TryFetchNextSource(this.sourceEnumerator, out string nextSource))
            {
                if (EqtTrace.IsVerboseEnabled)
                {
                    EqtTrace.Verbose("ProxyParallelDiscoveryManager: Triggering test discovery for next source: {0}", nextSource);
                }

                // Kick off another discovery task for the next source
                var discoveryCriteria = new DiscoveryCriteria(new[] { nextSource }, this.actualDiscoveryCriteria.FrequencyOfDiscoveredTestsEvent, this.actualDiscoveryCriteria.DiscoveredTestEventTimeout, this.actualDiscoveryCriteria.RunSettings);
                Task.Run(() =>
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose("ParallelProxyDiscoveryManager: Discovery started.");
                    }

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

                    // Send discovery complete. Similar logic is also used in ProxyDiscoveryManager.DiscoverTests.
                    // Differences:
                    // Total tests must be zero here since parallel discovery events handler adds the count
                    // Keep `lastChunk` as null since we don't want a message back to the IDE (discovery didn't even begin)
                    // Set `isAborted` as true since we want this instance of discovery manager to be replaced
                    this.GetHandlerForGivenManager(proxyDiscoveryManager).HandleDiscoveryComplete(-1, null, true);
                },
                              TaskContinuationOptions.OnlyOnFaulted);
            }

            if (EqtTrace.IsVerboseEnabled)
            {
                EqtTrace.Verbose("ProxyParallelDiscoveryManager: No sources available for discovery.");
            }
        }
Beispiel #16
0
        /// <summary>
        /// WaitForRunningEvent until vanguard initialization is finished
        /// </summary>
        private void WaitForRunningEvent()
        {
            EqtTrace.Info("Vanguard.WaitForRunningEvent: Waiting for CodeCoverage.exe initialization.");
            IntPtr runningEvent = CreateEvent(
                IntPtr.Zero,
                true,
                false,
                GlobalEventNamePrefix + this.sessionName + "_RUNNING");
            var timeout = EnvironmentHelper.GetConnectionTimeout();

            if (runningEvent != IntPtr.Zero)
            {
                uint waitTimeout = (uint)timeout * 1000; // Time limit for waiting for vanguard running event.

                IntPtr[] handles = new IntPtr[] { runningEvent, this.vanguardProcess.SafeHandle.DangerousGetHandle() };
                uint     result  = WaitForMultipleObjects((uint)handles.Length, handles, false, waitTimeout);
                CloseHandle(runningEvent);
                switch (result)
                {
                case WaitObject0:
                    EqtTrace.Info("Vanguard.WaitForRunningEvent: Running event received from CodeCoverage.exe.");
                    return;

                case WaitObject0 + 1:
                    // Process exited, something wrong happened
                    // we have already set to read messages asynchronously, so calling this.vanguardProcess.StandardError.ReadToEnd() which is synchronous is wrong.
                    // throw new VanguardException(string.Format(CultureInfo.CurrentCulture, Resources.ErrorLaunchVanguard, this.vanguardProcess.StandardError.ReadToEnd()));
                    EqtTrace.Error("Vanguard.WaitForRunningEvent: From CodeCoverage.exe failed to receive running event in {0} seconds", timeout);
                    throw new VanguardException(string.Format(CultureInfo.CurrentUICulture, Resources.NoRunningEventFromVanguard));
                }
            }

            // No running event received from code coverage.exe and not exited. Kill the CodeCoverage.exe.
            try
            {
                EqtTrace.Error("Vanguard.WaitForRunningEvent: Fail to create running event. Killing CodeCoverage.exe. ");
                this.vanguardProcess.Kill();
            }
            catch (Exception ex)
            {
                EqtTrace.Warning("Vanguard.WaitForRunningEvent: Fail to kill CodeCoverage.exe. process with exception: {0}", ex);
            }

            throw new VanguardException(string.Format(CultureInfo.CurrentUICulture, Resources.VanguardConnectionTimeout, timeout, EnvironmentHelper.VstestConnectionTimeout));
        }
Beispiel #17
0
        private void DiscoverTestsPrivate(ITestDiscoveryEventsHandler discoveryEventsHandler)
        {
            this.currentDiscoveryEventsHandler = discoveryEventsHandler;

            // Cleanup Task for cleaning up the parallel executors except for the default one
            // We do not do this in Sync so that this task does not add up to discovery time
            if (this.lastParallelDiscoveryCleanUpTask != null)
            {
                try
                {
                    this.lastParallelDiscoveryCleanUpTask.Wait();
                }
                catch (Exception ex)
                {
                    // if there is an exception disposing off concurrent hosts ignore it
                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning("ParallelProxyDiscoveryManager: Exception while invoking an action on DiscoveryManager: {0}", ex);
                    }
                }

                this.lastParallelDiscoveryCleanUpTask = null;
            }

            // Reset the discoverycomplete data
            this.discoveryCompletedClients = 0;

            // One data aggregator per parallel discovery
            this.currentDiscoveryDataAggregator = new ParallelDiscoveryDataAggregator();
            this.concurrentManagerHandlerMap    = new Dictionary <IProxyDiscoveryManager, ITestDiscoveryEventsHandler>();

            for (int i = 0; i < this.concurrentManagerInstances.Length; i++)
            {
                var concurrentManager = this.concurrentManagerInstances[i];

                var parallelEventsHandler = new ParallelDiscoveryEventsHandler(
                    concurrentManager,
                    discoveryEventsHandler,
                    this,
                    this.currentDiscoveryDataAggregator);
                this.concurrentManagerHandlerMap.Add(concurrentManager, parallelEventsHandler);

                Task.Run(() => this.DiscoverTestsOnConcurrentManager(concurrentManager));
            }
        }
Beispiel #18
0
        /// <summary>
        /// Verify/Normalize the test source files.
        /// </summary>
        /// <param name="sources"> Paths to source file to look for tests in.  </param>
        /// <param name="logger">logger</param>
        /// <returns> The list of verified sources. </returns>
        internal static IEnumerable <string> GetValidSources(IEnumerable <string> sources, IMessageLogger logger)
        {
            Debug.Assert(sources != null, "sources");
            var verifiedSources = new HashSet <string>(StringComparer.OrdinalIgnoreCase);

            foreach (string source in sources)
            {
                // It is possible that runtime provider sent relative source path for remote scenario.
                string src = !Path.IsPathRooted(source) ? Path.Combine(Directory.GetCurrentDirectory(), source) : source;

                if (!File.Exists(src))
                {
                    var errorMessage = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.FileNotFound, src);
                    logger.SendMessage(TestMessageLevel.Warning, errorMessage);

                    continue;
                }

                if (!verifiedSources.Add(src))
                {
                    var errorMessage = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.DuplicateSource, src);
                    logger.SendMessage(TestMessageLevel.Warning, errorMessage);
                }
            }

            // No valid source is found => we cannot discover.
            if (!verifiedSources.Any())
            {
                var sourcesString = string.Join(",", sources.ToArray());
                var errorMessage  = string.Format(CultureInfo.CurrentCulture, CrossPlatEngineResources.NoValidSourceFoundForDiscovery, sourcesString);
                logger.SendMessage(TestMessageLevel.Warning, errorMessage);

                EqtTrace.Warning("TestDiscoveryManager: None of the source {0} is valid. ", sourcesString);

                return(verifiedSources);
            }

            // Log the sources from where tests are being discovered
            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("TestDiscoveryManager: Discovering tests from sources {0}", string.Join(",", verifiedSources.ToArray()));
            }

            return(verifiedSources);
        }
        private async Task <Collection <AttachmentSet> > InternalProcessTestRunAttachmentsAsync(IRequestData requestData, Collection <AttachmentSet> attachments, ITestRunAttachmentsProcessingEventsHandler eventHandler, CancellationToken cancellationToken)
        {
            Stopwatch stopwatch = Stopwatch.StartNew();

            try
            {
                testPlatformEventSource.TestRunAttachmentsProcessingStart(attachments?.Count ?? 0);
                requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfAttachmentsSentForProcessing, attachments?.Count ?? 0);

                cancellationToken.ThrowIfCancellationRequested();

                var taskCompletionSource = new TaskCompletionSource <Collection <AttachmentSet> >();
                using (cancellationToken.Register(() => taskCompletionSource.TrySetCanceled()))
                {
                    Task <Collection <AttachmentSet> > task = Task.Run(async() => await ProcessAttachmentsAsync(new Collection <AttachmentSet>(attachments.ToList()), eventHandler, cancellationToken));

                    var completedTask = await Task.WhenAny(task, taskCompletionSource.Task).ConfigureAwait(false);

                    if (completedTask == task)
                    {
                        return(FinalizeOperation(requestData, new TestRunAttachmentsProcessingCompleteEventArgs(false, null), await task, stopwatch, eventHandler));
                    }
                    else
                    {
                        eventHandler?.HandleLogMessage(TestMessageLevel.Informational, "Attachments processing was cancelled.");
                        return(FinalizeOperation(requestData, new TestRunAttachmentsProcessingCompleteEventArgs(true, null), attachments, stopwatch, eventHandler));
                    }
                }
            }
            catch (OperationCanceledException)
            {
                if (EqtTrace.IsWarningEnabled)
                {
                    EqtTrace.Warning("TestRunAttachmentsProcessingManager: operation was cancelled.");
                }
                return(FinalizeOperation(requestData, new TestRunAttachmentsProcessingCompleteEventArgs(true, null), attachments, stopwatch, eventHandler));
            }
            catch (Exception e)
            {
                EqtTrace.Error("TestRunAttachmentsProcessingManager: Exception in ProcessTestRunAttachmentsAsync: " + e);

                eventHandler?.HandleLogMessage(TestMessageLevel.Error, e.Message);
                return(FinalizeOperation(requestData, new TestRunAttachmentsProcessingCompleteEventArgs(false, e), attachments, stopwatch, eventHandler));
            }
        }
Beispiel #20
0
        /// <summary>
        /// Invoked when log messages are received
        /// </summary>
        public void HandleLogMessage(TestMessageLevel level, string message)
        {
            EqtTrace.Verbose("TestRunRequest:SendTestRunMessage: Starting.");

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

                this.TestRunMessage.SafeInvoke(this, new TestRunMessageEventArgs(level, message), "TestRun.LogMessages");
            }

            EqtTrace.Info("TestRunRequest:SendTestRunMessage: Completed.");
        }
Beispiel #21
0
        /// <summary>
        /// Gets the data collection data stored in the in process data collection sink
        /// </summary>
        /// <param name="testCaseId">valid test case id</param>
        /// <returns>test data collection dictionary </returns>
        public IDictionary <string, string> GetDataCollectionDataSetForTestCase(Guid testCaseId)
        {
            TestCaseDataCollectionData testCaseDataCollection = null;

            if (!this.testCaseDataCollectionDataMap.TryGetValue(testCaseId, out testCaseDataCollection))
            {
                if (EqtTrace.IsWarningEnabled)
                {
                    EqtTrace.Warning("No DataCollection Data set for the test case {0}", testCaseId);
                }
                return(new Dictionary <string, string>());
            }
            else
            {
                this.testCaseDataCollectionDataMap.Remove(testCaseId);
                return(testCaseDataCollection.CollectionData);
            }
        }
Beispiel #22
0
        public MetricsPublisher()
        {
#if NET451
            try
            {
                this.session           = new TelemetrySession(TelemetryService.DefaultSession.SerializeSettings());
                this.session.IsOptedIn = true;
                this.session.Start();
            }
            catch (Exception e)
            {
                if (EqtTrace.IsWarningEnabled)
                {
                    EqtTrace.Warning(string.Format(CultureInfo.InvariantCulture, "TelemetrySession: Error in starting Telemetry session : {0}", e.Message));
                }
            }
#endif
        }
Beispiel #23
0
        /// <summary>
        /// Get the Version for the target framework version string
        /// </summary>
        /// <param name="version">Target framework string</param>
        /// <returns>Framework Version</returns>
        internal static Version GetTargetFrameworkVersionFromVersionString(string version)
        {
            try
            {
                if (version.Length > PlatformServices.Constants.DotNetFrameWorkStringPrefix.Length + 1)
                {
                    string versionPart = version.Substring(PlatformServices.Constants.DotNetFrameWorkStringPrefix.Length + 1);
                    return(new Version(versionPart));
                }
            }
            catch (FormatException ex)
            {
                // if the version is ".NETPortable,Version=v4.5,Profile=Profile259", then above code will throw exception.
                EqtTrace.Warning(string.Format("AppDomainUtilities.GetTargetFrameworkVersionFromVersionString: Could not create version object from version string '{0}' due to error '{1}':", version, ex.Message));
            }

            return(defaultVersion);
        }
        /// <summary>
        /// Initialize
        /// </summary>
        /// <param name="configurationElement">Configuration element</param>
        /// <param name="dataSink">Data sink</param>
        /// <param name="logger">Logger</param>
        public virtual void Initialize(
            XmlElement configurationElement,
            IDataCollectionSink dataSink,
            IDataCollectionLogger logger)
        {
            var defaultConfigurationElement = DynamicCoverageDataCollectorImpl.GetDefaultConfiguration();

            try
            {
                var processor = new CodeCoverageRunSettingsProcessor(defaultConfigurationElement);
                configurationElement = (XmlElement)processor.Process(configurationElement);
            }
            catch (Exception ex)
            {
                EqtTrace.Warning(
                    string.Format(
                        CultureInfo.CurrentCulture,
                        string.Join(
                            " ",
                            "DynamicCoverageDataCollectorImpl.Initialize: Exception encountered while processing the configuration element.",
                            "Keeping the configuration element unaltered. More info about the exception: {0}"),
                        ex.Message));
            }

            EqtTrace.Info("DynamicCoverageDataCollectorImpl.Initialize: Initialize configuration. ");
            if (string.IsNullOrEmpty(configurationElement?.InnerXml))
            {
                configurationElement = defaultConfigurationElement;
            }

            this.logger   = logger;
            this.dataSink = dataSink;

            this.dataSink.SendFileCompleted += this.OnSendFileCompletedEvent;

            this.SessionName = Guid.NewGuid().ToString();

            this.sessionDirectory = Path.Combine(Path.GetTempPath(), this.SessionName);
            this.directoryHelper.CreateDirectory(this.sessionDirectory);

            this.SetCoverageFileName(configurationElement);

            this.PrepareVanguardProcess(configurationElement);
        }
        private int StartTestRunPrivate(ITestRunEventsHandler runEventsHandler)
        {
            this.currentRunEventsHandler = runEventsHandler;

            // Cleanup Task for cleaning up the parallel executors except for the default one
            // We do not do this in Sync so that this task does not add up to execution time
            if (this.lastParallelRunCleanUpTask != null)
            {
                try
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Verbose("ProxyParallelExecutionManager: Wait for last cleanup to complete.");
                    }

                    this.lastParallelRunCleanUpTask.Wait();
                }
                catch (Exception ex)
                {
                    // if there is an exception disposing off concurrent executors ignore it
                    if (EqtTrace.IsWarningEnabled)
                    {
                        EqtTrace.Warning("ProxyParallelExecutionManager: Exception while invoking an action on ProxyExecutionManager: {0}", ex);
                    }
                }

                this.lastParallelRunCleanUpTask = null;
            }

            // Reset the runcomplete data
            this.runCompletedClients = 0;

            // One data aggregator per parallel run
            this.currentRunDataAggregator = new ParallelRunDataAggregator();

            foreach (var concurrentManager in this.GetConcurrentManagerInstances())
            {
                var parallelEventsHandler = this.GetEventsHandler(concurrentManager);
                this.UpdateHandlerForManager(concurrentManager, parallelEventsHandler);
                this.StartTestRunOnConcurrentManager(concurrentManager);
            }

            return(1);
        }
Beispiel #26
0
        private void OnProjectUnloaded(object sender, ProjectEventArgs e)
        {
            if (e.Project != null)
            {
                string root = null;
                try
                {
                    root = e.Project.GetProjectHome();
                }
                catch (Exception ex)
                {
                    if (EqtTrace.IsVerboseEnabled)
                    {
                        EqtTrace.Warning("TestContainerDiscoverer: Failed to get project home {0}", ex);
                    }
                    // If we fail to get ProjectHome, we still want to track the
                    // project. We just won't get the benefits of merging
                    // watchers into a single recursive watcher.
                }

                ProjectInfo projectInfo;
                string      projectPath;
                if (e.Project.TryGetProjectPath(out projectPath) &&
                    _knownProjects.TryGetValue(projectPath, out projectInfo))
                {
                    _knownProjects.Remove(projectPath);

                    foreach (var p in e.Project.GetProjectItemPaths())
                    {
                        if (string.IsNullOrEmpty(root) || !CommonUtils.IsSubpathOf(root, p))
                        {
                            _testFilesUpdateWatcher.RemoveWatch(p);
                        }
                        _fileRootMap.Remove(p);
                    }
                    if (!string.IsNullOrEmpty(root))
                    {
                        _testFilesUpdateWatcher.RemoveWatch(root);
                    }
                }
            }

            OnTestContainersChanged(e.Project);
        }
        private void CheckSourcesForCompatibility(Framework chosenFramework, Architecture chosenPlatform, IDictionary <string, Architecture> sourcePlatforms, IDictionary <string, Framework> sourceFrameworks, IBaseTestEventsRegistrar registrar)
        {
            // Find compatible sources
            var compatibleSources = InferRunSettingsHelper.FilterCompatibleSources(chosenPlatform, chosenFramework, sourcePlatforms, sourceFrameworks, out var incompatibleSettingWarning);

            // Raise warnings for incompatible sources
            if (!string.IsNullOrEmpty(incompatibleSettingWarning))
            {
                EqtTrace.Warning(incompatibleSettingWarning);
                registrar?.LogWarning(incompatibleSettingWarning);
            }

            // Log compatible sources
            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("Compatible sources list : ");
                EqtTrace.Info(string.Join("\n", compatibleSources.ToArray()));
            }
        }
Beispiel #28
0
        private bool TryToRunInSTAThread(Action action, bool waitForCompletion)
        {
            bool success = true;

            try
            {
                EqtTrace.Verbose("BaseRunTests.TryToRunInSTAThread: Using STA thread to call adapter API.");
                this.platformThread.Run(action, PlatformApartmentState.STA, waitForCompletion);
            }
            catch (ThreadApartmentStateNotSupportedException ex)
            {
                success = false;
                EqtTrace.Warning("BaseRunTests.TryToRunInSTAThread: Failed to run in STA thread: {0}", ex);
                this.TestRunEventsHandler.HandleLogMessage(TestMessageLevel.Warning,
                                                           string.Format(CultureInfo.CurrentUICulture, Resources.ExecutionThreadApartmentStateNotSupportedForFramework, runConfiguration.TargetFrameworkVersion.ToString()));
            }

            return(success);
        }
Beispiel #29
0
        private string TryReceiveRawMessage()
        {
            string message             = null;
            var    receiverMessageTask = this.communicationManager.ReceiveRawMessageAsync(this.clientExitCancellationSource.Token);

            receiverMessageTask.Wait();
            message = receiverMessageTask.Result;

            if (message == null)
            {
                EqtTrace.Warning("TestRequestSender: Communication channel with test host is broken.");
                var reason = CommonResources.UnableToCommunicateToTestHost;
                if (!string.IsNullOrWhiteSpace(this.clientExitErrorMessage))
                {
                    reason = this.clientExitErrorMessage;
                }
                else
                {
                    // Test host process has not exited yet. We will wait for exit to allow us gather
                    // standard error
                    var processWaitEvent = new ManualResetEventSlim();
                    try
                    {
                        EqtTrace.Info("TestRequestSender: Waiting for test host to exit.");
                        processWaitEvent.Wait(TimeSpan.FromSeconds(10), this.clientExitCancellationSource.Token);

                        // Use a default error message
                        EqtTrace.Info("TestRequestSender: Timed out waiting for test host to exit.");
                        reason = CommonResources.UnableToCommunicateToTestHost;
                    }
                    catch (OperationCanceledException)
                    {
                        EqtTrace.Info("TestRequestSender: Got error message from test host.");
                        reason = this.clientExitErrorMessage;
                    }
                }

                EqtTrace.Error("TestRequestSender: Unable to receive message from testhost: {0}", reason);
                throw new IOException(reason);
            }

            return(message);
        }
        private void Initialize(XmlElement configurationElement)
        {
            if (configurationElement == null)
            {
                // There is no configuration
                return;
            }

            // Iterate through top-level XML elements within the configuration element and store
            // name/value information for elements that have name/value attributes.
            foreach (XmlNode settingNode in configurationElement.ChildNodes)
            {
                // Skip all non-elements
                var settingElement = settingNode as XmlElement;
                if (settingElement == null)
                {
                    continue;
                }

                // Get the setting name
                string settingName = settingElement.Name;

                // Get the setting value
                string settingValue = settingElement.InnerText;

                if (string.IsNullOrWhiteSpace(settingValue))
                {
                    EqtTrace.Warning("Skipping configuration setting '{0}' due to missing value", settingName);
                    continue;
                }

                // Save the name/value pair in the dictionary. Note that duplicate settings are
                // overwritten with the last occurrence's value.
                if (this.nameValuePairs.ContainsKey(settingName))
                {
                    EqtTrace.Verbose(
                        "Duplicate configuration setting found for '{0}'. Using the last setting.",
                        settingName);
                }

                this.NameValuePairs[settingName] = settingValue;
            }
        }