public void InvalidNodeIdOnNodeLoggingContext() { Assert.Throws<InternalErrorException>(() => { NodeLoggingContext context = new NodeLoggingContext(new MockLoggingService(), -2, true); } ); }
/// <summary> /// Constructs a project logging context. /// </summary> internal ProjectLoggingContext(NodeLoggingContext nodeLoggingContext, BuildRequest request, string projectFullPath, string toolsVersion, BuildEventContext parentBuildEventContext) : this ( nodeLoggingContext, request.SubmissionId, request.ConfigurationId, projectFullPath, request.Targets, toolsVersion, null, null, parentBuildEventContext ) { }
/// <summary> /// Constructs a project logging context. /// </summary> internal ProjectLoggingContext(NodeLoggingContext nodeLoggingContext, BuildRequestEntry requestEntry, BuildEventContext parentBuildEventContext) : this ( nodeLoggingContext, requestEntry.Request.SubmissionId, requestEntry.Request.ConfigurationId, requestEntry.RequestConfiguration.ProjectFullPath, requestEntry.Request.Targets, requestEntry.RequestConfiguration.ToolsVersion, requestEntry.RequestConfiguration.Project.PropertiesToBuildWith, requestEntry.RequestConfiguration.Project.ItemsToBuildWith, parentBuildEventContext ) { }
public void CreateValidNodeLoggingContexts() { NodeLoggingContext context = new NodeLoggingContext(new MockLoggingService(), 1, true); Assert.Equal(true, context.IsInProcNode); Assert.True(context.IsValid); context.LogBuildFinished(true); Assert.False(context.IsValid); Assert.Equal(1, context.BuildEventContext.NodeId); NodeLoggingContext context2 = new NodeLoggingContext(new MockLoggingService(), 2, false); Assert.Equal(false, context2.IsInProcNode); Assert.True(context2.IsValid); context2.LogBuildFinished(true); Assert.False(context2.IsValid); Assert.Equal(2, context2.BuildEventContext.NodeId); }
/// <summary> /// Constructs a project logging context. /// </summary> internal ProjectLoggingContext( NodeLoggingContext nodeLoggingContext, BuildRequest request, string projectFullPath, string toolsVersion, int evaluationId = BuildEventContext.InvalidEvaluationId) : this ( nodeLoggingContext, request.SubmissionId, request.ConfigurationId, projectFullPath, request.Targets, toolsVersion, projectProperties : null, projectItems : null, request.ParentBuildEventContext, evaluationId ) { }
/// <summary> /// Not Implemented /// </summary> public void BuildRequest(NodeLoggingContext nodeLoggingContext, BuildRequestEntry entry) { throw new NotImplementedException(); }
/// <summary> /// Constructs a project logging contexts. /// </summary> private ProjectLoggingContext(NodeLoggingContext nodeLoggingContext, int submissionId, int configurationId, string projectFullPath, List <string> targets, string toolsVersion, PropertyDictionary <ProjectPropertyInstance> projectProperties, ItemDictionary <ProjectItemInstance> projectItems, BuildEventContext parentBuildEventContext) : base(nodeLoggingContext) { _nodeLoggingContext = nodeLoggingContext; _projectFullPath = projectFullPath; ProjectPropertyInstanceEnumeratorProxy properties = null; ProjectItemInstanceEnumeratorProxy items = null; IEnumerable <ProjectPropertyInstance> projectPropertiesEnumerator = projectProperties == null?Array.Empty <ProjectPropertyInstance>() : null; IEnumerable <ProjectItemInstance> projectItemsEnumerator = projectItems == null?Array.Empty <ProjectItemInstance>() : null; string[] propertiesToSerialize = LoggingService.PropertiesToSerialize; // If we are only logging critical events lets not pass back the items or properties if (!LoggingService.OnlyLogCriticalEvents && (!LoggingService.RunningOnRemoteNode || LoggingService.SerializeAllProperties)) { if (projectProperties != null) { projectPropertiesEnumerator = projectProperties.GetCopyOnReadEnumerable(); } if (projectItems != null) { projectItemsEnumerator = projectItems.GetCopyOnReadEnumerable(); } properties = new ProjectPropertyInstanceEnumeratorProxy(projectPropertiesEnumerator); items = new ProjectItemInstanceEnumeratorProxy(projectItemsEnumerator); } if (projectProperties != null && propertiesToSerialize?.Length > 0 && !LoggingService.SerializeAllProperties) { PropertyDictionary <ProjectPropertyInstance> projectPropertiesToSerialize = new PropertyDictionary <ProjectPropertyInstance>(); foreach (string propertyToGet in propertiesToSerialize) { ProjectPropertyInstance instance = projectProperties[propertyToGet]; { if (instance != null) { projectPropertiesToSerialize.Set(instance); } } } properties = new ProjectPropertyInstanceEnumeratorProxy(projectPropertiesToSerialize); } this.BuildEventContext = LoggingService.LogProjectStarted ( nodeLoggingContext.BuildEventContext, submissionId, configurationId, parentBuildEventContext, projectFullPath, String.Join(";", targets), properties, items ); LoggingService.LogComment(this.BuildEventContext, MessageImportance.Low, "ToolsVersionInEffectForBuild", toolsVersion); this.IsValid = true; }
/// <summary> /// Prepares the build request engine to run a build. /// </summary> /// <param name="loggingContext">The logging context to use.</param> /// <remarks> /// Called by the Node. Non-overlapping with other calls from the Node.</remarks> public void InitializeForBuild(NodeLoggingContext loggingContext) { ErrorUtilities.VerifyThrow(_componentHost != null, "BuildRequestEngine not initialized by component host."); ErrorUtilities.VerifyThrow(_status == BuildRequestEngineStatus.Uninitialized, "Engine must be in the Uninitiailzed state, but is {0}", _status); _nodeLoggingContext = loggingContext; // Create a work queue that will take an action and invoke it. The generic parameter is the type which ActionBlock.Post() will // take (an Action in this case) and the parameter to this constructor is a function which takes that parameter of type Action // (which we have named action) and does something with it (in this case calls invoke on it.) _workQueue = new ActionBlock<Action>(action => action.Invoke()); ChangeStatus(BuildRequestEngineStatus.Idle); }
private ProjectLoggingContext( NodeLoggingContext nodeLoggingContext, int submissionId, int configurationId, string projectFullPath, List <string> targets, string toolsVersion, PropertyDictionary <ProjectPropertyInstance> projectProperties, ItemDictionary <ProjectItemInstance> projectItems, BuildEventContext parentBuildEventContext, int evaluationId, int projectContextId) : base(nodeLoggingContext) { _projectFullPath = projectFullPath; IEnumerable <DictionaryEntry> properties = null; IEnumerable <DictionaryEntry> items = null; string[] propertiesToSerialize = LoggingService.PropertiesToSerialize; // If we are only logging critical events lets not pass back the items or properties if (!LoggingService.OnlyLogCriticalEvents && !LoggingService.IncludeEvaluationPropertiesAndItems && (!LoggingService.RunningOnRemoteNode || LoggingService.SerializeAllProperties)) { properties = projectProperties?.GetCopyOnReadEnumerable(property => new DictionaryEntry(property.Name, property.EvaluatedValue)) ?? Enumerable.Empty <DictionaryEntry>(); items = projectItems?.GetCopyOnReadEnumerable(item => new DictionaryEntry(item.ItemType, new TaskItem(item))) ?? Enumerable.Empty <DictionaryEntry>(); } if (projectProperties != null && !LoggingService.IncludeEvaluationPropertiesAndItems && propertiesToSerialize?.Length > 0 && !LoggingService.SerializeAllProperties) { PropertyDictionary <ProjectPropertyInstance> projectPropertiesToSerialize = new PropertyDictionary <ProjectPropertyInstance>(); foreach (string propertyToGet in propertiesToSerialize) { ProjectPropertyInstance instance = projectProperties[propertyToGet]; { if (instance != null) { projectPropertiesToSerialize.Set(instance); } } } properties = projectPropertiesToSerialize.Select((ProjectPropertyInstance property) => new DictionaryEntry(property.Name, property.EvaluatedValue)); } this.BuildEventContext = LoggingService.LogProjectStarted ( nodeLoggingContext.BuildEventContext, submissionId, configurationId, parentBuildEventContext, projectFullPath, string.Join(";", targets), properties, items, evaluationId, projectContextId ); // No need to log a redundant message in the common case if (toolsVersion != "Current") { LoggingService.LogComment(this.BuildEventContext, MessageImportance.Low, "ToolsVersionInEffectForBuild", toolsVersion); } this.IsValid = true; }
/// <summary> /// Handles the NodeConfiguration packet. /// </summary> private void HandleNodeConfiguration(NodeConfiguration configuration) { // Grab the system parameters. _buildParameters = configuration.BuildParameters; _buildParameters.ProjectRootElementCache = s_projectRootElementCache; // Snapshot the current environment _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables(); // Change to the startup directory try { NativeMethodsShared.SetCurrentDirectory(BuildParameters.StartupDirectory); } catch (DirectoryNotFoundException) { // Somehow the startup directory vanished. This can happen if build was started from a USB Key and it was removed. NativeMethodsShared.SetCurrentDirectory(Environment.SystemDirectory); } // Replicate the environment. First, unset any environment variables set by the previous configuration. if (_currentConfiguration != null) { foreach (string key in _currentConfiguration.BuildParameters.BuildProcessEnvironment.Keys) { Environment.SetEnvironmentVariable(key, null); } } // Now set the new environment foreach (KeyValuePair<string, string> environmentPair in _buildParameters.BuildProcessEnvironment) { Environment.SetEnvironmentVariable(environmentPair.Key, environmentPair.Value); } // We want to make sure the global project collection has the toolsets which were defined on the parent // so that any custom toolsets defined can be picked up by tasks who may use the global project collection but are // executed on the child node. ICollection<Toolset> parentToolSets = _buildParameters.ToolsetProvider.Toolsets; if (parentToolSets != null) { ProjectCollection.GlobalProjectCollection.RemoveAllToolsets(); foreach (Toolset toolSet in parentToolSets) { ProjectCollection.GlobalProjectCollection.AddToolset(toolSet); } } // Set the culture. Thread.CurrentThread.CurrentCulture = _buildParameters.Culture; Thread.CurrentThread.CurrentUICulture = _buildParameters.UICulture; // Get the node ID. _buildParameters.NodeId = configuration.NodeId; _buildParameters.IsOutOfProc = true; // And the AppDomainSetup _buildParameters.AppDomainSetup = configuration.AppDomainSetup; // Set up the logging service. LoggingServiceFactory loggingServiceFactory = new LoggingServiceFactory(LoggerMode.Asynchronous, configuration.NodeId); _componentFactories.ReplaceFactory(BuildComponentType.LoggingService, loggingServiceFactory.CreateInstance); _loggingService = _componentFactories.GetComponent(BuildComponentType.LoggingService) as ILoggingService; BuildEventArgTransportSink sink = new BuildEventArgTransportSink(SendLoggingPacket); _shutdownException = null; try { // If there are no node loggers to initialize dont do anything if (configuration.LoggerDescriptions != null && configuration.LoggerDescriptions.Length > 0) { _loggingService.InitializeNodeLoggers(configuration.LoggerDescriptions, sink, configuration.NodeId); } } catch (Exception ex) { if (ExceptionHandling.IsCriticalException(ex)) { throw; } OnEngineException(ex); } _loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException); string forwardPropertiesFromChild = Environment.GetEnvironmentVariable("MSBUILDFORWARDPROPERTIESFROMCHILD"); string[] propertyListToSerialize = null; // Get a list of properties which should be serialized if (!String.IsNullOrEmpty(forwardPropertiesFromChild)) { propertyListToSerialize = forwardPropertiesFromChild.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); } _loggingService.PropertiesToSerialize = propertyListToSerialize; _loggingService.RunningOnRemoteNode = true; string forwardAllProperties = Environment.GetEnvironmentVariable("MSBUILDFORWARDALLPROPERTIESFROMCHILD"); if (String.Equals(forwardAllProperties, "1", StringComparison.OrdinalIgnoreCase) || _buildParameters.LogInitialPropertiesAndItems) { _loggingService.SerializeAllProperties = true; } else { _loggingService.SerializeAllProperties = false; } // Now prep the buildRequestEngine for the build. _loggingContext = new NodeLoggingContext(_loggingService, configuration.NodeId, false /* inProcNode */); if (_shutdownException != null) { Exception exception; HandleShutdown(out exception); throw exception; } _buildRequestEngine.InitializeForBuild(_loggingContext); // Finally store off this configuration packet. _currentConfiguration = configuration; }
/// <summary> /// Perform necessary actions to shut down the node. /// </summary> private NodeEngineShutdownReason HandleShutdown(out Exception exception) { if (_debugCommunications) { using (StreamWriter writer = File.CreateText(String.Format(CultureInfo.CurrentCulture, Path.Combine(Path.GetTempPath(), @"MSBuild_NodeShutdown_{0}.txt"), Process.GetCurrentProcess().Id))) { writer.WriteLine("Node shutting down with reason {0} and exception: {1}", _shutdownReason, _shutdownException); } } // Clean up the engine if (null != _buildRequestEngine && _buildRequestEngine.Status != BuildRequestEngineStatus.Uninitialized) { _buildRequestEngine.CleanupForBuild(); if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse) { ((IBuildComponent)_buildRequestEngine).ShutdownComponent(); } } // Dispose of any build registered objects IRegisteredTaskObjectCache objectCache = (IRegisteredTaskObjectCache)(_componentFactories.GetComponent(BuildComponentType.RegisteredTaskObjectCache)); objectCache.DisposeCacheObjects(RegisteredTaskObjectLifetime.Build); if (_shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse) { // Dispose of any node registered objects. ((IBuildComponent)objectCache).ShutdownComponent(); } // Shutdown any Out Of Proc Nodes Created _taskHostNodeManager.ShutdownConnectedNodes(_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse); // Restore the original current directory. NativeMethodsShared.SetCurrentDirectory(Environment.SystemDirectory); // Restore the original environment. // If the node was never configured, this will be null. if (_savedEnvironment != null) { foreach (KeyValuePair<string, string> entry in CommunicationsUtilities.GetEnvironmentVariables()) { if (!_savedEnvironment.ContainsKey(entry.Key)) { Environment.SetEnvironmentVariable(entry.Key, null); } } foreach (KeyValuePair<string, string> entry in _savedEnvironment) { Environment.SetEnvironmentVariable(entry.Key, entry.Value); } } try { // Shut down logging, which will cause all queued logging messages to be sent. if (null != _loggingContext && null != _loggingService) { _loggingContext.LogBuildFinished(true); ((IBuildComponent)_loggingService).ShutdownComponent(); } } finally { // Shut down logging, which will cause all queued logging messages to be sent. if (null != _loggingContext && null != _loggingService) { _loggingContext.LoggingService.OnLoggingThreadException -= new LoggingExceptionDelegate(OnLoggingThreadException); _loggingContext = null; } exception = _shutdownException; if (_nodeEndpoint.LinkStatus == LinkStatus.Active) { // Notify the BuildManager that we are done. _nodeEndpoint.SendData(new NodeShutdown(_shutdownReason == NodeEngineShutdownReason.Error ? NodeShutdownReason.Error : NodeShutdownReason.Requested, exception)); // Flush all packets to the pipe and close it down. This blocks until the shutdown is complete. _nodeEndpoint.OnLinkStatusChanged -= new LinkStatusChangedDelegate(OnLinkStatusChanged); } _nodeEndpoint.Disconnect(); CleanupCaches(); } return _shutdownReason; }
public void InvalidNodeIdOnNodeLoggingContext() { NodeLoggingContext context = new NodeLoggingContext(new MockLoggingService(), -2, true); }