private void SetCommunicationEndPoint() { if (this.connectionInfo.Role == ConnectionRole.Host) { this.communicationEndPoint = new SocketServer(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("TestRequestHanlder is acting as server"); } } else { this.communicationEndPoint = new SocketClient(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("TestRequestHanlder is acting as client"); } } }
/// <summary> /// Connects to server async /// </summary> /// <param name="endpoint">EndPointAddress for client to connect</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task SetupClientAsync(IPEndPoint endpoint) { // ToDo: pass cancellationtoken, if user cancels the operation, so we don't wait 50 secs to connect // for now added a check for validation of this.tcpclient this.clientConnectionAcceptedEvent.Reset(); EqtTrace.Info("Trying to connect to server on socket : {0} ", endpoint); this.tcpClient = new TcpClient { NoDelay = true }; this.socket = this.tcpClient.Client; Stopwatch watch = new Stopwatch(); watch.Start(); do { try { await this.tcpClient.ConnectAsync(endpoint.Address, endpoint.Port); if (this.tcpClient.Connected) { // Using Buffered stream only in case of write, and Network stream in case of read. var bufferedStream = new PlatformStream().CreateBufferedStream(this.tcpClient.GetStream(), SocketConstants.BufferSize); var networkStream = this.tcpClient.GetStream(); this.binaryReader = new BinaryReader(networkStream); this.binaryWriter = new BinaryWriter(bufferedStream); if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("Connected to the server successfully "); EqtTrace.Info("Using the buffer size of {0} bytes", SocketConstants.BufferSize); } this.clientConnectionAcceptedEvent.Set(); } } catch (Exception ex) { EqtTrace.Verbose("Connection Failed with error {0}, retrying", ex.ToString()); } }while ((this.tcpClient != null) && !this.tcpClient.Connected && watch.ElapsedMilliseconds < CONNECTIONRETRYTIMEOUT); }
/// <summary> /// Disposes datacollector. /// </summary> internal void DisposeDataCollector() { try { if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("dataCollectorInfo.DisposeDataCollector: calling Dispose() on {0}", this.DataCollector.GetType()); } this.DataCollector.Dispose(); } catch (Exception ex) { if (EqtTrace.IsErrorEnabled) { EqtTrace.Error("DataCollectorInfo.DisposeDataCollector: exception while calling Dispose() on {0}: " + ex, this.DataCollector.GetType()); } } }
internal TestRunRequest(IRequestData requestData, TestRunCriteria testRunCriteria, IProxyExecutionManager executionManager, ITestLoggerManager loggerManager, IDataSerializer dataSerializer) { Debug.Assert(testRunCriteria != null, "Test run criteria cannot be null"); Debug.Assert(executionManager != null, "ExecutionManager cannot be null"); Debug.Assert(requestData != null, "request Data is null"); Debug.Assert(loggerManager != null, "LoggerManager cannot be null"); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("TestRunRequest.ExecuteAsync: Creating test run request."); } this.testRunCriteria = testRunCriteria; this.ExecutionManager = executionManager; this.LoggerManager = loggerManager; this.State = TestRunState.Pending; this.dataSerializer = dataSerializer; this.requestData = requestData; }
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.TargetFramework.ToString())); } return(success); }
/// <summary> /// Invoked before starting of test run. /// </summary> /// <param name="settingsXml">Specifies the settings which are being used for the run.</param> /// <param name="resetDataCollectors">Forces the data collectors to be reset.</param> /// <param name="isRunStartingNow">Specifies whether run is going to start immediately.</param> /// <returns>Enivronment variables for the executor.</returns> public BeforeTestRunStartResult BeforeTestRunStart(string settingsXml, bool resetDataCollectors, bool isRunStartingNow) { if (this.dataCollectionManagers == null || this.dataCollectionManagers.Length == 0) { return(null); } if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionCoordinator: BeforeTestRunStart Entering."); } var runSettings = RunSettingsUtilities.CreateAndInitializeRunSettings(settingsXml); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionCoordinator: Loading/Initializing the data collectors"); } // Load the collectors and get the environment variables var environmentVariables = this.LoadDataCollectors(runSettings); var areTestCaseLevelEventsRequired = false; if (isRunStartingNow) { if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionCoordinator: Raising session started event."); } // Raise SessionStart event to loaded data collection plugins. areTestCaseLevelEventsRequired = this.SessionStarted(); } if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionCoordinator: BeforeTestRunStart Exiting areTestCaseLevelEventsRequired={0}.", areTestCaseLevelEventsRequired); } // todo : Get Data Collection Port here return(new BeforeTestRunStartResult(environmentVariables, areTestCaseLevelEventsRequired, 0)); }
internal static int GetParentPidWindows(Process process) { try { var handle = process.Handle; PROCESS_BASIC_INFORMATION pbi; int size; var res = NtQueryInformationProcess(handle, 0, out pbi, Marshal.SizeOf <PROCESS_BASIC_INFORMATION>(), out size); var p = res != 0 ? InvalidProcessId : pbi.InheritedFromUniqueProcessId.ToInt32(); return(p); } catch (Exception ex) { EqtTrace.Verbose($"ProcessCodeMethods.GetParentPidLinux: Error getting parent of process {process.Id} - {process.ProcessName}, {ex}."); return(InvalidProcessId); } }
/// <inheritdoc/> public virtual TestProcessStartInfo GetTestHostProcessStartInfo( IEnumerable <string> sources, IDictionary <string, string> environmentVariables, TestRunnerConnectionInfo connectionInfo) { // Default test host manager supports shared test sources var testHostProcessName = (this.architecture == Architecture.X86) ? X86TestHostProcessName : X64TestHostProcessName; var currentWorkingDirectory = Path.GetDirectoryName(typeof(DefaultTestHostManager).GetTypeInfo().Assembly.Location); var argumentsString = " " + connectionInfo.ToCommandLineOptions(); var currentProcessPath = this.processHelper.GetCurrentProcessFileName(); if (currentProcessPath.EndsWith("dotnet", StringComparison.OrdinalIgnoreCase) || currentProcessPath.EndsWith("dotnet.exe", StringComparison.OrdinalIgnoreCase)) { // "TestHost" is the name of the folder which contain Full CLR built testhost package assemblies inside Core CLR package folder. testHostProcessName = Path.Combine("TestHost", testHostProcessName); } if (!this.Shared) { // Not sharing the host which means we need to pass the test assembly path as argument // so that the test host can create an appdomain on startup (Main method) and set appbase argumentsString += " " + "--testsourcepath " + "\"" + sources.FirstOrDefault() + "\""; } var testhostProcessPath = Path.Combine(currentWorkingDirectory, testHostProcessName); EqtTrace.Verbose("DefaultTestHostmanager: Full path of {0} is {1}", testHostProcessName, testhostProcessPath); // For IDEs and other scenario, current directory should be the // working directory (not the vstest.console.exe location). // For VS - this becomes the solution directory for example // "TestResults" directory will be created at "current directory" of test host var processWorkingDirectory = Directory.GetCurrentDirectory(); return(new TestProcessStartInfo { FileName = testhostProcessPath, Arguments = argumentsString, EnvironmentVariables = environmentVariables ?? new Dictionary <string, string>(), WorkingDirectory = processWorkingDirectory }); }
private void OnClientConnected(TcpClient client) { this.tcpClient = client; this.tcpClient.Client.NoDelay = true; if (this.Connected != null) { this.channel = this.channelFactory(this.tcpClient.GetStream()); this.Connected.SafeInvoke(this, new ConnectedEventArgs(this.channel), "SocketServer: ClientConnected"); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("SocketServer.OnClientConnected: Client connected for endPoint: {0}, starting MessageLoopAsync:", this.endPoint); } // Start the message loop Task.Run(() => this.tcpClient.MessageLoopAsync(this.channel, error => this.Stop(error), this.cancellation.Token)).ConfigureAwait(false); } }
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; } }
/// <summary> /// Handles discovery complete event. /// </summary> /// <param name="e">DiscoveryComplete event args.</param> public void HandleDiscoveryComplete(DiscoveryCompleteEventArgs e) { if (!this.isDisposed) { try { this.loggerEvents.RaiseDiscoveryComplete(e); } finally { this.Dispose(); } } else { // Note: We are not raising warning in case testLoggerManager is disposed as HandleRawMessage and HandleDiscoveryComplete both can call HandleDiscoveryComplete. EqtTrace.Verbose("TestLoggerManager.HandleDiscoveryComplete: Ignoring as the object is disposed."); } }
/// <inheritdoc/> public BeforeTestRunStartResult SendBeforeTestRunStartAndGetResult(string settingsXml, IEnumerable <string> sources, bool isTelemetryOptedIn, ITestMessageEventHandler runEventsHandler) { var isDataCollectionStarted = false; BeforeTestRunStartResult result = null; if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionRequestSender.SendBeforeTestRunStartAndGetResult : Send BeforeTestRunStart message with settingsXml {0} and sources {1}: ", settingsXml, sources.ToString()); } var payload = new BeforeTestRunStartPayload { SettingsXml = settingsXml, Sources = sources, IsTelemetryOptedIn = isTelemetryOptedIn }; this.communicationManager.SendMessage(MessageType.BeforeTestRunStart, payload); while (!isDataCollectionStarted) { var message = this.communicationManager.ReceiveMessage(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DataCollectionRequestSender.SendBeforeTestRunStartAndGetResult : Received message: {0}", message); } if (message.MessageType == MessageType.DataCollectionMessage) { var dataCollectionMessageEventArgs = this.dataSerializer.DeserializePayload <DataCollectionMessageEventArgs>(message); this.LogDataCollectorMessage(dataCollectionMessageEventArgs, runEventsHandler); } else if (message.MessageType == MessageType.BeforeTestRunStartResult) { isDataCollectionStarted = true; result = this.dataSerializer.DeserializePayload <BeforeTestRunStartResult>(message); } } return(result); }
/// <summary> /// Call vstest.console with the parameters previously specified /// </summary> public void StartProcess(ConsoleParameters consoleParameters) { var info = new ProcessStartInfo(GetConsoleRunner(), string.Join(" ", BuildArguments(consoleParameters))) { UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }; EqtTrace.Verbose("VsTestCommandLineWrapper: Process Start Info {0} {1}", info.FileName, info.Arguments); #if NETFRAMEWORK if (consoleParameters.EnvironmentVariables != null) { info.EnvironmentVariables.Clear(); foreach (var envVariable in consoleParameters.EnvironmentVariables) { if (envVariable.Key != null) { info.EnvironmentVariables.Add(envVariable.Key.ToString(), envVariable.Value?.ToString()); } } } #endif this.process = Process.Start(info); lock (syncObject) { vstestConsoleExited = false; vstestConsoleStarted = true; } this.process.EnableRaisingEvents = true; this.process.Exited += Process_Exited; this.process.OutputDataReceived += Process_OutputDataReceived; this.process.ErrorDataReceived += Process_ErrorDataReceived; this.process.BeginOutputReadLine(); this.process.BeginErrorReadLine(); processExitedEvent.Reset(); }
/// <summary> /// Updates the run settings XML with the specified values. /// </summary> /// <param name="runSettingsDocument"> The XmlDocument of the XML. </param> /// <param name="architecture"> The architecture. </param> /// <param name="framework"> The framework. </param> /// <param name="resultsDirectory"> The results directory. </param> public static void UpdateRunSettingsWithUserProvidedSwitches(XmlDocument runSettingsDocument, Architecture architecture, Framework framework, string resultsDirectory) { var runSettingsNavigator = runSettingsDocument.CreateNavigator(); ValidateRunConfiguration(runSettingsNavigator); // when runsettings specifies platform, that takes precedence over the user specified platform via command line arguments. var shouldUpdatePlatform = true; string nodeXml; TryGetPlatformXml(runSettingsNavigator, out nodeXml); if (!string.IsNullOrEmpty(nodeXml)) { architecture = (Architecture)Enum.Parse(typeof(Architecture), nodeXml, true); shouldUpdatePlatform = false; } // when runsettings specifies framework, that takes precedence over the user specified input framework via the command line arguments. var shouldUpdateFramework = true; TryGetFrameworkXml(runSettingsNavigator, out nodeXml); if (!string.IsNullOrEmpty(nodeXml)) { framework = Framework.FromString(nodeXml); shouldUpdateFramework = false; } EqtTrace.Verbose("Using effective platform:{0} effective framework:{1}", architecture, framework); // check if platform is compatible with current system architecture. VerifyCompatibilityWithOSArchitecture(architecture); // Check if inputRunSettings has results directory configured. var hasResultsDirectory = runSettingsDocument.SelectSingleNode(ResultsDirectoryNodePath) != null; // Regenerate the effective settings. if (shouldUpdatePlatform || shouldUpdateFramework || !hasResultsDirectory) { UpdateRunConfiguration(runSettingsDocument, architecture, framework, resultsDirectory); } }
public static void Setup() { EqtTrace.Info("Setting up debug trace listener."); // in the majority of cases there will be only a single DefaultTraceListener in this collection // and we will replace that with our listener, in case there are listeners of different types we keep // them as is for (var i = 0; i < Trace.Listeners.Count; i++) { var listener = Trace.Listeners[i]; if (listener is DefaultTraceListener) { EqtTrace.Verbose($"TestPlatformTraceListener.Setup: Replacing listener {0} with { nameof(TestHostTraceListener) }.", Trace.Listeners[i]); Trace.Listeners[i] = new TestHostTraceListener(); } } EqtTrace.Verbose("TestPlatformTraceListener.Setup: Added test platform trace listener."); // this is a netcoreapp2.1 only fix, but because we always compile against netcoreapp2.1 // and upgrade the executable as necessary this needs to be a runtime check and not a compile time // check. This call returns ".NET Core 4.6.xxx" on netcore 2.1 and older, and ".NET Core 3.1.xxx" // or the respective version on the newer runtimes if (System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET Core 4.6")) { try { // workaround for netcoreapp2.1 where the trace listener api is not called when // Debug.Assert fails. This method is internal, but the class is on purpose keeping the // callback settable so tests can set the callback var field = typeof(Debug).GetField("s_ShowDialog", BindingFlags.Static | BindingFlags.NonPublic); if (field != null) { var value = field.GetValue(null); field.SetValue(null, (Action <string, string, string, string>)ShowDialog); } } catch (Exception ex) { EqtTrace.Error("TestPlatformTraceListener.Setup: Failed to replace inner callback to ShowDialog in Debug.Assert. Calls to Debug.Assert with crash the test host process. {0}", ex); } } }
/// <summary> /// Start the discovery request /// </summary> void IDiscoveryRequest.DiscoverAsync() { if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DiscoveryRequest.DiscoverAsync: Starting."); } lock (this.syncObject) { if (this.disposed) { throw new ObjectDisposedException("DiscoveryRequest"); } // Reset the discovery completion event this.discoveryCompleted.Reset(); this.discoveryInProgress = true; try { this.discoveryStartTime = DateTime.UtcNow; // Collecting Data Point Number of sources sent for discovery this.requestData.MetricsCollection.Add(TelemetryDataConstants.NumberOfSourcesSentForDiscovery, (this.DiscoveryCriteria.Sources.Count()).ToString()); // Invoke OnDiscoveryStart event this.OnDiscoveryStart.SafeInvoke(this, new DiscoveryStartEventArgs(this.DiscoveryCriteria), "DiscoveryRequest.DiscoveryStart"); this.DiscoveryManager.DiscoverTests(this.DiscoveryCriteria, this); } catch { this.discoveryInProgress = false; throw; } } if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("DiscoveryRequest.DiscoverAsync: Started."); } }
/// <summary> /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> public void Dispose() { if (this.parentDomainAssemblyResolver != null) { this.parentDomainAssemblyResolver.Dispose(); this.parentDomainAssemblyResolver = null; } if (this.childDomainAssemblyResolver != null) { this.childDomainAssemblyResolver.Dispose(); this.childDomainAssemblyResolver = null; } if (this.domain != null) { try { this.appDomain.Unload(this.domain); } catch (Exception exception) { // This happens usually when a test spawns off a thread and fails to clean it up. EqtTrace.Error("DesktopTestSourceHost.Dispose(): The app domain running tests could not be unloaded. Exception: {0}", exception); if (this.frameworkHandle != null) { // Let the test platform know that it should tear down the test host process // since we have issues in unloading appdomain. We do so to avoid any assembly locking issues. this.frameworkHandle.EnableShutdownAfterTestRun = true; EqtTrace.Verbose("DesktopTestSourceHost.Dispose(): Notifying the test platform that the test host process should be shut down because the app domain running tests could not be unloaded successfully."); } } this.domain = null; } this.ResetContext(); GC.SuppressFinalize(this); }
/// <inheritdoc /> public Task Send(string data) { try { // Writing Message on binarywriter is not Thread-Safe // Need to sync one by one to avoid buffer corruption lock (this.writeSyncObject) { this.writer.Write(data); this.writer.Flush(); } } catch (Exception ex) { EqtTrace.Verbose("LengthPrefixCommunicationChannel: Error sending data: {0}.", ex); throw new CommunicationException("Unable to send data over channel.", ex); } return(Task.FromResult(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, don't do anything if (this.disposed) { EqtTrace.Warning("TestRunRequest.SendTestRunMessage: Ignoring as the object is disposed."); return; } var testRunMessageEvent = new TestRunMessageEventArgs(level, message); this.LoggerManager.HandleTestRunMessage(testRunMessageEvent); this.TestRunMessage.SafeInvoke(this, testRunMessageEvent, "TestRun.LogMessages"); } EqtTrace.Info("TestRunRequest:SendTestRunMessage: Completed."); }
private int LaunchHost(TestProcessStartInfo testHostStartInfo) { this.testHostProcessStdError = new StringBuilder(this.ErrorLength, this.ErrorLength); if (this.testHostLauncher == null) { EqtTrace.Verbose("DotnetTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments); this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack) as Process; } else { var processId = this.testHostLauncher.LaunchTestHost(testHostStartInfo); this.testHostProcess = Process.GetProcessById(processId); } var pId = this.testHostProcess != null ? this.testHostProcess.Id : 0; this.OnHostLaunched(new HostProviderEventArgs("Test Runtime launched with Pid: " + pId)); return(pId); }
private void SetCommunicationEndPoint() { // TODO: Use factory to get the communication endpoint. It will abstract out the type of communication endpoint like socket, shared memory or named pipe etc., if (this.connectionInfo.Role == ConnectionRole.Client) { this.communicationEndpoint = new SocketClient(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("TestRequestSender is acting as client"); } } else { this.communicationEndpoint = new SocketServer(); if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("TestRequestSender is acting as server"); } } }
/// <summary> /// Handles test run complete. /// </summary> /// <param name="e">TestRunComplete event args.</param> public void HandleTestRunComplete(TestRunCompleteEventArgs e) { if (!this.isDisposed) { try { this.loggerEvents.CompleteTestRun(e.TestRunStatistics, e.IsCanceled, e.IsAborted, e.Error, e.AttachmentSets, e.ElapsedTimeInRunningTests); } finally { this.Dispose(); } } else { // Note: We are not raising warning in case testLoggerManager is disposed as HandleRawMessage and HandleTestRunComplete both can call HandleTestRunComplete. EqtTrace.Verbose("TestLoggerManager.HandleTestRunComplete: Ignoring as the object is disposed."); } }
/// <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); } this.GetHandlerForGivenManager(proxyDiscoveryManager).HandleDiscoveryComplete(0, Enumerable.Empty <TestCase>(), true); }, TaskContinuationOptions.OnlyOnFaulted); } if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("ProxyParallelDiscoveryManager: No sources available for discovery."); } }
/// <summary> /// Wait for discovery completion /// </summary> /// <param name="timeout"> The timeout. </param> bool IRequest.WaitForCompletion(int timeout) { if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("DiscoveryRequest.WaitForCompletion: Waiting with timeout {0}.", timeout); } if (this.disposed) { throw new ObjectDisposedException("DiscoveryRequest"); } // This method is not synchronized as it can lead to dead-lock // (the discoveryCompletionEvent cannot be raised unless that lock is released) if (this.discoveryCompleted != null) { return(this.discoveryCompleted.WaitOne(timeout)); } return(true); }
/// <summary> /// Dispose the run /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { EqtTrace.Verbose("TestRunRequest.Dispose: Starting."); lock (this.syncObject) { if (!this.disposed) { if (disposing) { this.runCompletionEvent?.Dispose(); } // Indicate that object has been disposed this.runCompletionEvent = null; this.disposed = true; } } EqtTrace.Info("TestRunRequest.Dispose: Completed."); }
private bool LaunchHost(TestProcessStartInfo testHostStartInfo, CancellationToken cancellationToken) { this.testHostProcessStdError = new StringBuilder(0, CoreUtilities.Constants.StandardErrorMaxLength); if (this.customTestHostLauncher == null) { EqtTrace.Verbose("DotnetTestHostManager: Starting process '{0}' with command line '{1}'", testHostStartInfo.FileName, testHostStartInfo.Arguments); cancellationToken.ThrowIfCancellationRequested(); this.testHostProcess = this.processHelper.LaunchProcess(testHostStartInfo.FileName, testHostStartInfo.Arguments, testHostStartInfo.WorkingDirectory, testHostStartInfo.EnvironmentVariables, this.ErrorReceivedCallback, this.ExitCallBack, null) as Process; } else { var processId = this.customTestHostLauncher.LaunchTestHost(testHostStartInfo, cancellationToken); this.testHostProcess = Process.GetProcessById(processId); this.processHelper.SetExitCallback(processId, this.ExitCallBack); } this.OnHostLaunched(new HostProviderEventArgs("Test Runtime launched", 0, this.testHostProcess.Id)); return(this.testHostProcess != null); }
/// <inheritdoc /> public int LaunchProcessWithDebuggerAttached(TestProcessStartInfo testProcessStartInfo) { var waitHandle = new ManualResetEventSlim(false); Message ackMessage = null; this.onAckMessageRecieved = (ackRawMessage) => { ackMessage = ackRawMessage; waitHandle.Set(); }; var data = dataSerializer.SerializePayload(MessageType.LaunchAdapterProcessWithDebuggerAttached, testProcessStartInfo, protocolVersion); this.SendData(data); EqtTrace.Verbose("Waiting for LaunchAdapterProcessWithDebuggerAttached ack"); waitHandle.Wait(); this.onAckMessageRecieved = null; return(this.dataSerializer.DeserializePayload <int>(ackMessage)); }
/// <summary> /// Log the extensions /// </summary> private void LogExtensions() { if (EqtTrace.IsVerboseEnabled) { var discoverers = this.TestExtensions.TestDiscoverers != null?string.Join(",", this.TestExtensions.TestDiscoverers.Keys.ToArray()) : null; EqtTrace.Verbose("TestPluginCache: Discoverers are '{0}'.", discoverers); var executors = this.TestExtensions.TestExecutors != null?string.Join(",", this.TestExtensions.TestExecutors.Keys.ToArray()) : null; EqtTrace.Verbose("TestPluginCache: Executors are '{0}'.", executors); var settingsProviders = this.TestExtensions.TestSettingsProviders != null?string.Join(",", this.TestExtensions.TestSettingsProviders.Keys.ToArray()) : null; EqtTrace.Verbose("TestPluginCache: Setting providers are '{0}'.", settingsProviders); var loggers = this.TestExtensions.TestLoggers != null?string.Join(",", this.TestExtensions.TestLoggers.Keys.ToArray()) : null; EqtTrace.Verbose("TestPluginCache: Loggers are '{0}'.", loggers); } }
/// <inheritdoc /> public Architecture GetArchitecture(string assemblyPath) { Architecture archType = Architecture.AnyCPU; try { // AssemblyName won't load the assembly into current domain. var assemblyName = AssemblyName.GetAssemblyName(assemblyPath); archType = MapToArchitecture(assemblyName.ProcessorArchitecture); } catch (Exception ex) { // AssemblyName will thorw Exception if assembly contains native code or no manifest. if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("AssemblyMetadataProvider.GetArchitecture: Failed get ProcessorArchitecture using AssemblyName API with exception: {0}", ex); } try { archType = GetArchitectureForSource(assemblyPath); } catch (Exception e) { if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("AssemblyMetadataProvider.GetArchitecture: Failed to determine Assembly Architecture with exception: {0}", e); } } } if (EqtTrace.IsInfoEnabled) { EqtTrace.Info("AssemblyMetadataProvider.GetArchitecture: Determined architecture:{0} info for assembly: {1}", archType, assemblyPath); } return(archType); }
public int StartTestRun(TestRunCriteria testRunCriteria, ITestRunEventsHandler eventHandler) { this.hasSpecificTestsRun = testRunCriteria.HasSpecificTests; this.actualTestRunCriteria = testRunCriteria; if (this.hasSpecificTestsRun) { var testCasesBySource = new Dictionary <string, List <TestCase> >(); foreach (var test in testRunCriteria.Tests) { if (!testCasesBySource.ContainsKey(test.Source)) { testCasesBySource.Add(test.Source, new List <TestCase>()); } testCasesBySource[test.Source].Add(test); } // Do not use "Dictionary.ValueCollection.Enumerator" - it becomes undetermenstic once we go out of scope of this method // Use "ToArray" to copy ValueColleciton to a simple array and use it's enumerator // Set the enumerator for parallel yielding of testCases // Whenever a concurrent executor becomes free, it picks up the next set of testCases using this enumerator var testCaseLists = testCasesBySource.Values.ToArray(); this.testCaseListEnumerator = testCaseLists.GetEnumerator(); this.availableTestSources = testCaseLists.Length; } else { // Set the enumerator for parallel yielding of sources // Whenever a concurrent executor becomes free, it picks up the next source using this enumerator this.sourceEnumerator = testRunCriteria.Sources.GetEnumerator(); this.availableTestSources = testRunCriteria.Sources.Count(); } if (EqtTrace.IsVerboseEnabled) { EqtTrace.Verbose("ParallelProxyExecutionManager: Start execution. Total sources: " + this.availableTestSources); } return(this.StartTestRunPrivate(eventHandler)); }