/// <summary> /// Executes each of the requests and waits for all of them to be completed. /// </summary> /// <param name="buildRequests">Array of BuildRequestData to be built.</param> /// <param name="timeout">Number of mili seconds to wait for the pending build requests.</param> /// <param name="waitForCompletion">Should wait for the builds to complete.</param> /// <param name="asyncBuildRequestsStatus">Array of AsyncBuildRequestStatus which contain information about each request executed asynchronously.</param> /// <returns>True if the builds completed successfully.</returns> public bool ExecuteAsyncBuildRequests(BuildRequestData[] buildRequests, int timeout, bool waitForCompletion, out AsyncBuildRequestStatus[] asyncBuildRequestsStatus) { BuildSubmissionTestExtension[] submissionTestExtensions = new BuildSubmissionTestExtension[buildRequests.Length]; AutoResetEvent[] buildCompletedEvents = new AutoResetEvent[buildRequests.Length]; asyncBuildRequestsStatus = new AsyncBuildRequestStatus[buildRequests.Length]; try { for (int i = 0; i < buildRequests.Length; i++) { buildCompletedEvents[i] = new AutoResetEvent(false); submissionTestExtensions[i] = this.PendBuildRequest(buildRequests[i]); asyncBuildRequestsStatus[i] = new AsyncBuildRequestStatus(buildCompletedEvents[i], submissionTestExtensions[i]); submissionTestExtensions[i].ExecuteAsync(asyncBuildRequestsStatus[i].SubmissionCompletedCallback, null); } if (waitForCompletion) { if (!BuildManagerTestExtension.WaitAll(buildCompletedEvents, timeout)) { return(false); } return(true); } else { return(true); } } finally { if (waitForCompletion) { for (int i = 0; i < buildRequests.Length; i++) { buildCompletedEvents[i].Close(); buildCompletedEvents[i] = null; } } } }
/// <summary> /// Method to mimic WaitAll in STA. WaitAll for multiple handles on an STA thread is not supported. /// </summary> /// <param name="waitHandles">Handles to wait for.</param> /// <param name="timeout">Number of miliseconds to wait for before timing out.</param> /// <returns>True if the wait succeedes.</returns> public static bool WaitAll(WaitHandle[] waitHandles, int timeout) { bool waitStatus = true; if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA) { foreach (WaitHandle myWaitHandle in waitHandles) { if (!BuildManagerTestExtension.Wait(myWaitHandle, timeout)) { return(false); } } } else { waitStatus = WaitHandle.WaitAll(waitHandles); } return(waitStatus); }
/// <summary> /// Responsible for creating the build manager. /// For MSBuild backend testing BuildManager is the Entry point for all tests. That is - the environment /// for testing starts with the BuildManager. Configuration can specify which components should be mocked /// and which test extension should be attached to which component. /// </summary> /// <returns>TextExtensions created.</returns> protected override TestExtensionContainer Generate() { List <TestExtension> testExtensions = new List <TestExtension>(); // To workaround the problem where extensions derived out from Testextension does not have a LifeTimeManagmentService. LifeTimeManagmentServiceTestExtension lifetimeServiceExtension = new LifeTimeManagmentServiceTestExtension(LifetimeService); LifetimeService.Compose(lifetimeServiceExtension); testExtensions.Add(lifetimeServiceExtension); // Create the build manager and the associated test extension first. BuildManagerTestExtension buildManagerTestExtension = new BuildManagerTestExtension(BuildManager.DefaultBuildManager); LifetimeService.Compose(buildManagerTestExtension); testExtensions.Add(buildManagerTestExtension); // When the BuildManager is created it registers a default set of components. // Loop through each of the components that we want to mock and then replace the component in the BuildManager. foreach (KeyValuePair <ComponentType, string> componentTypePair in this.Configuration.ComponentsToMock) { buildManagerTestExtension.ReplaceRegisterdFactory(GetBuildComponentTypeFromComponentType(componentTypePair.Key.ToString()), this.CreateMockComponent); } // Loop through each of the components that we want to wrap with a test extension - create the test extension and aggregate the internal component. // This component could be a mock that we create above or the real implementation. foreach (KeyValuePair <ComponentType, string> componentTypePair in this.Configuration.TestExtensionForComponents) { TestExtension extension = CreateTestExtensionForComponent(componentTypePair.Key.ToString(), componentTypePair.Value, buildManagerTestExtension); LifetimeService.Compose(extension); testExtensions.Add(extension); } TestExtensionContainer testContainer = new TestExtensionContainer(testExtensions); return(testContainer); }
/// <summary> /// Create a TestExtension for a given component type. /// </summary> /// <param name="componentName">Name of the component for which the TestExtension is to be created.</param> /// <param name="testExtensionName">Fully qualified TestExtension name.</param> /// <param name="buildManagerTestExtension">BuildManager Test extension entry.</param> /// <returns>New TestExtension.</returns> private static TestExtension CreateTestExtensionForComponent(string componentName, string testExtensionName, BuildManagerTestExtension buildManagerTestExtension) { BuildComponentType type = StringToEnum <BuildComponentType>(componentName); IBuildComponent component = buildManagerTestExtension.GetComponent(type); Type testExtensionType = Assembly.GetAssembly(typeof(BuildManagerContainerGenerator)).GetType(testExtensionName, true, true); object[] parameters = { component }; return((TestExtension)testExtensionType.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, parameters, CultureInfo.InvariantCulture)); }