public void SetUp() { // Whole bunch of setup code. XmlElement taskNode = new XmlDocument().CreateElement("MockTask"); LoadedType taskClass = new LoadedType(typeof(MockTask), new AssemblyLoadInfo(typeof(MockTask).Assembly.FullName, null)); Engine engine = new Engine(@"c:\"); loggingHelper = new EngineLoggingServicesHelper(); engine.LoggingServices = loggingHelper; Project project = new Project(engine); taskExecutionModule = new MockTaskExecutionModule(new EngineCallback(engine)); // Set up some "fake data" which will be passed to the Task Execution State object Hashtable[] fakeArray = new Hashtable[1]; fakeArray[0] = new Hashtable(); projectLevelProprtiesForInference = new BuildPropertyGroup(); projectLevelPropertiesForExecution = new BuildPropertyGroup(); inferenceBucketItemsByName = fakeArray; inferenceBucketMetaData = fakeArray; projectLevelItemsForInference = new Hashtable(); executionBucketItemsByName = fakeArray; executionBucketMetaData = fakeArray; projectLevelItemsForExecution = new Hashtable(); hostObject = null; projectFileOfTaskNode = "In Memory"; parentProjectFullFileName = project.FullFileName; nodeProxyId = engine.EngineCallback.CreateTaskContext(project, null, null, taskNode, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId)); executionDirectory = Directory.GetCurrentDirectory(); projectId = project.Id; }
public void SetUp() { // Whole bunch of setup code. XmlElement taskNode = new XmlDocument().CreateElement("MockTask"); LoadedType taskClass = new LoadedType(typeof(MockTask), new AssemblyLoadInfo(typeof(MockTask).Assembly.FullName, null)); engine = new Engine(@"c:\"); Project project = new Project(engine); EngineCallback engineCallback = new EngineCallback(engine); taskExecutionModule = new MockTaskExecutionModule(engineCallback); int handleId = engineCallback.CreateTaskContext(project, null, null, taskNode, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId)); TaskEngine taskEngine = new TaskEngine ( taskNode, null, /* host object */ "In Memory", project.FullFileName, engine.LoggingServices, handleId, taskExecutionModule, null ); taskEngine.TaskClass = taskClass; engineProxy = new EngineProxy(taskExecutionModule, handleId, project.FullFileName, project.FullFileName, engine.LoggingServices, null); taskExecutionModule2 = new MockTaskExecutionModule(engineCallback, TaskExecutionModule.TaskExecutionModuleMode.MultiProcFullNodeMode); engineProxy2 = new EngineProxy(taskExecutionModule2, handleId, project.FullFileName, project.FullFileName, engine.LoggingServices, null); }
/// <summary> /// Creates an instance of a MockTask, and returns the objects necessary to exercise /// taskEngine.InitializeTask /// </summary> /// <param name="taskNode"></param> /// <param name="taskEngine"></param> /// <param name="mockTask"></param> /// <param name="itemBucket"></param> /// <owner>RGoel</owner> private void InstantiateMockTaskHelper ( XmlElement taskNode, out TaskEngine taskEngine, out MockTask mockTask, out ItemBucket itemBucket, out EngineProxy engineProxy, string condition ) { LoadedType taskClass = new LoadedType(typeof(MockTask), new AssemblyLoadInfo(typeof(MockTask).Assembly.FullName, null)); Engine engine = new Engine(@"c:\"); Project project = new Project(engine); EngineCallback engineCallback = new EngineCallback(engine); TaskExecutionModule taskExecutionModule = new TaskExecutionModule(engineCallback, TaskExecutionModule.TaskExecutionModuleMode.SingleProcMode, false); ProjectBuildState buildContext = new ProjectBuildState(null, null, new BuildEventContext(0, 1, 1, 1)); int nodeProxyID = engineCallback.CreateTaskContext(project, null, buildContext, taskNode, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId)); taskEngine = new TaskEngine ( taskNode, null, /* host object */ "In Memory", project.FullFileName, engine.LoggingServices, nodeProxyID, taskExecutionModule, new BuildEventContext(0, 1, 1, 1) ); taskEngine.TaskClass = taskClass; engineProxy = new EngineProxy(taskExecutionModule, nodeProxyID, project.FullFileName, project.FullFileName, engine.LoggingServices, null); mockTask = new MockTask(new EngineProxy(taskExecutionModule, nodeProxyID, project.FullFileName, project.FullFileName, engine.LoggingServices, null)); // The code below creates an item table that is equivalent to the following MSBuild syntax: // // <ItemGroup> // <ItemListContainingOneItem Include="a.cs"> // <Culture>fr-fr</Culture> // </ItemListContainingOneItem> // // <ItemListContainingTwoItems Include="b.cs"> // <HintPath>c:\foo</HintPath> // </ItemListContainingTwoItems> // <ItemListContainingTwoItems Include="c.cs"> // <HintPath>c:\bar</HintPath> // </ItemListContainingTwoItems> // </ItemGroup> // Hashtable itemsByName = new Hashtable(StringComparer.OrdinalIgnoreCase); BuildItemGroup itemListContainingOneItem = new BuildItemGroup(); BuildItem a = itemListContainingOneItem.AddNewItem("ItemListContainingOneItem", "a.cs"); a.SetMetadata("Culture", "fr-fr"); itemsByName["ItemListContainingOneItem"] = itemListContainingOneItem; BuildItemGroup itemListContainingTwoItems = new BuildItemGroup(); BuildItem b = itemListContainingTwoItems.AddNewItem("ItemListContainingTwoItems", "b.cs"); b.SetMetadata("HintPath", "c:\\foo"); BuildItem c = itemListContainingTwoItems.AddNewItem("ItemListContainingTwoItems", "c.cs"); c.SetMetadata("HintPath", "c:\\bar"); itemsByName["ItemListContainingTwoItems"] = itemListContainingTwoItems; itemBucket = new ItemBucket(new string[0], new Dictionary<string, string>(), LookupHelpers.CreateLookup(itemsByName), 0); }
private List<TaskExecutionStateHelper> InitializeTaskState() { BuildPropertyGroup projectLevelProprtiesForInference; BuildPropertyGroup projectLevelPropertiesForExecution; Hashtable[] inferenceBucketItemsByName; Hashtable[] inferenceBucketMetaData; Hashtable projectLevelItemsForInference; Hashtable[] executionBucketItemsByName; Hashtable[] executionBucketMetaData; Hashtable projectLevelItemsForExecution; ITaskHost hostObject; EngineLoggingServicesHelper loggingHelper; string projectFileOfTaskNode; string parentProjectFullFileName; int nodeProxyId; int projectId; string executionDirectory; XmlElement taskNode = new XmlDocument().CreateElement("MockTask"); LoadedType taskClass = new LoadedType(typeof(MockTask), new AssemblyLoadInfo(typeof(MockTask).Assembly.FullName, null)); loggingHelper = new EngineLoggingServicesHelper(); engine.LoggingServices = loggingHelper; Project project = new Project(engine); nodeProxyId = engine.EngineCallback.CreateTaskContext(project, null, null, taskNode, EngineCallback.inProcNode, new BuildEventContext(BuildEventContext.InvalidNodeId, BuildEventContext.InvalidTargetId, BuildEventContext.InvalidProjectContextId, BuildEventContext.InvalidTaskId)); // Set up some "fake data" which will be passed to the Task Execution State object Hashtable[] fakeArray = new Hashtable[1]; fakeArray[0] = new Hashtable(); projectLevelProprtiesForInference = new BuildPropertyGroup(); projectLevelPropertiesForExecution = new BuildPropertyGroup(); inferenceBucketItemsByName = fakeArray; inferenceBucketMetaData = fakeArray; projectLevelItemsForInference = new Hashtable(); executionBucketItemsByName = fakeArray; executionBucketMetaData = fakeArray; projectLevelItemsForExecution = new Hashtable(); hostObject = null; projectFileOfTaskNode = "In Memory"; parentProjectFullFileName = project.FullFileName; executionDirectory = Directory.GetCurrentDirectory(); projectId = project.Id; MockTaskExecutionModule taskExecutionModule = taskExecutionModule = new MockTaskExecutionModule(new EngineCallback(engine)); TaskExecutionMode howToExecuteTask = TaskExecutionMode.InferOutputsOnly; List<TaskExecutionStateHelper> executionStates = new List<TaskExecutionStateHelper>(); TaskExecutionStateHelper executionStateNormal1 = new TaskExecutionStateHelper( howToExecuteTask, LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference), LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution), taskNode, hostObject, projectFileOfTaskNode, parentProjectFullFileName, executionDirectory, nodeProxyId); executionStateNormal1.LoggingService = loggingHelper; executionStateNormal1.TargetInferenceSuccessful = true; executionStateNormal1.ParentModule = taskExecutionModule; executionStates.Add(executionStateNormal1); TaskExecutionStateHelper executionStateCallBack = new TaskExecutionStateHelper( howToExecuteTask, LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference), LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution), taskNode, hostObject, projectFileOfTaskNode, parentProjectFullFileName, executionDirectory, nodeProxyId); executionStateCallBack.LoggingService = loggingHelper; executionStateCallBack.TargetInferenceSuccessful = true; executionStates.Add(executionStateCallBack); TaskExecutionStateHelper executionStateNormal2 = new TaskExecutionStateHelper( howToExecuteTask, LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference), LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution), taskNode, hostObject, projectFileOfTaskNode, parentProjectFullFileName, executionDirectory, nodeProxyId); executionStateNormal2.LoggingService = loggingHelper; executionStateNormal2.TargetInferenceSuccessful = true; executionStateNormal2.ParentModule = taskExecutionModule; executionStates.Add(executionStateNormal2); TaskExecutionStateHelper executionStateNormal3 = new TaskExecutionStateHelper( howToExecuteTask, LookupHelpers.CreateLookup(projectLevelProprtiesForInference, projectLevelItemsForInference), LookupHelpers.CreateLookup(projectLevelPropertiesForExecution, projectLevelItemsForExecution), taskNode, hostObject, projectFileOfTaskNode, parentProjectFullFileName, executionDirectory, nodeProxyId); executionStateNormal3.LoggingService = loggingHelper; executionStateNormal3.TargetInferenceSuccessful = true; executionStateNormal3.ParentModule = taskExecutionModule; executionStates.Add(executionStateNormal3); return executionStates; }
/// <summary> /// Given a task name, this method retrieves the task class. If the task has been requested before, it will be found in /// the class cache; otherwise, <UsingTask> declarations will be used to search the appropriate assemblies. /// </summary> /// <param name="taskName"></param> /// <param name="taskProjectFile"></param> /// <param name="taskNode"></param> /// <param name="exactMatchRequired"></param> /// <param name="loggingServices"></param> /// <param name="buildEventContext"></param> /// <param name="taskClass"></param> /// <returns>true, if task is found</returns> public bool GetRegisteredTask ( string taskName, string taskProjectFile, XmlNode taskNode, bool exactMatchRequired, EngineLoggingServices loggingServices, BuildEventContext buildEventContext, out LoadedType taskClass ) { taskClass = null; // If there are no using tags in the project don't bother caching or looking for tasks if (registeredTasks == null) { return false; } Hashtable cachedTaskClasses = exactMatchRequired ? this.cachedTaskClassesWithExactMatch : this.cachedTaskClassesWithFuzzyMatch; if (cachedTaskClasses.Contains(taskName)) { // Caller has asked us before for this same task name, and for the same value of "bool exactMatchRequired". // Return whatever the previous result was, even if it was null. Why would the result be different than // it was before? NOTE: Hash tables CAN have "null" as their value, and this still returns "true" for Contains(...). taskClass = (LoadedType) cachedTaskClasses[taskName]; } else { Hashtable registeredTasksFound; // look for the given task name in the registry; if not found, gather all registered task names that partially // match the given name if (FindRegisteredTasks(taskName, exactMatchRequired, out registeredTasksFound)) { foreach (DictionaryEntry registeredTaskFound in registeredTasksFound) { string mostSpecificTaskName = (string)registeredTaskFound.Key; // if the given task name is longer than the registered task name if (taskName.Length > ((string)registeredTaskFound.Key).Length) { // we will use the longer name to help disambiguate between multiple matches mostSpecificTaskName = taskName; } if (GetTaskFromAssembly(mostSpecificTaskName, (ArrayList)registeredTaskFound.Value, taskProjectFile, taskNode, loggingServices, buildEventContext, out taskClass)) { // Whilst we are within the processing of the task, we haven't actually started executing it, so // our using task message needs to be in the context of the target. However any errors should be reported // at the point where the task appears in the project. BuildEventContext usingTaskContext = new BuildEventContext(buildEventContext.NodeId, buildEventContext.TargetId, buildEventContext.ProjectContextId, BuildEventContext.InvalidTaskId); loggingServices.LogComment(usingTaskContext, "TaskFound", taskName, taskClass.Assembly.ToString()); break; } } } // Cache the result, even if it is null. We should never again do the work we just did, for this task name. cachedTaskClasses[taskName] = taskClass; } return (taskClass != null); }
/// <summary> /// Given a task name and a list of assemblies, this helper method checks if the task exists in any of the assemblies. /// </summary> /// <remarks> /// If the task name is fully qualified, then a match (if any) is unambiguous; otherwise, if there are multiple tasks with /// the same name in different namespaces/assemblies, the first task found will be returned. /// </remarks> /// <param name="taskName"></param> /// <param name="taskAssemblies"></param> /// <param name="taskProjectFile"></param> /// <param name="taskNode"></param> /// <param name="loggingServices"></param> /// <param name="buildEventContext"></param> /// <param name="taskClass"></param> /// <returns>true, if task is successfully loaded</returns> private bool GetTaskFromAssembly ( string taskName, ArrayList taskAssemblies, string taskProjectFile, XmlNode taskNode, EngineLoggingServices loggingServices, BuildEventContext buildEventContext, out LoadedType taskClass ) { taskClass = null; foreach (AssemblyLoadInfo assembly in taskAssemblies) { try { taskClass = typeLoader.Load(taskName, assembly); } catch (TargetInvocationException e) { // Exception thrown by the called code itself // Log the stack, so the task vendor can fix their code ProjectErrorUtilities.VerifyThrowInvalidProject(false, taskNode, "TaskLoadFailure", taskName, assembly.ToString(), Environment.NewLine + e.InnerException.ToString()); } catch (ReflectionTypeLoadException e) { // ReflectionTypeLoadException.LoaderExceptions may contain nulls foreach (Exception exception in e.LoaderExceptions) { if (exception != null) { loggingServices.LogError(buildEventContext, new BuildEventFileInfo(taskProjectFile), "TaskLoadFailure", taskName, assembly.ToString(), exception.Message); } } ProjectErrorUtilities.VerifyThrowInvalidProject(false, taskNode, "TaskLoadFailure", taskName, assembly.ToString(), e.Message); } catch (Exception e) // Catching Exception, but rethrowing unless it's a well-known exception. { if (ExceptionHandling.NotExpectedReflectionException(e)) throw; ProjectErrorUtilities.VerifyThrowInvalidProject(false, taskNode, "TaskLoadFailure", taskName, assembly.ToString(), e.Message); } if (taskClass != null) { return true; } } return false; }