public void InvalidNodeIdOnNodeLoggingContext()
 {
     Assert.Throws<InternalErrorException>(() =>
     {
         NodeLoggingContext context = new NodeLoggingContext(new MockLoggingService(), -2, true);
     }
    );
 }
Example #2
0
 /// <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
     )
 {
 }
Example #3
0
 /// <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
     )
 {
 }
Example #6
0
 /// <summary>
 /// Not Implemented
 /// </summary>
 public void BuildRequest(NodeLoggingContext nodeLoggingContext, BuildRequestEntry entry)
 {
     throw new NotImplementedException();
 }
Example #7
0
        /// <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;
        }
Example #8
0
        /// <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);
        }
Example #9
0
        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;
        }
Example #10
0
        /// <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;
        }
Example #11
0
        /// <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);
 }