public void TestSimpleStateProgression() { // Start in Ready BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary <string, string>(), "foo", Array.Empty <string>(), null), "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); Assert.Equal(BuildRequestEntryState.Ready, entry.State); Assert.Equal(entry.Request, request); Assert.Null(entry.Result); // Move to active. Should not be any results yet. IDictionary <int, BuildResult> results = entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); Assert.Null(entry.Result); Assert.Null(results); // Wait for results, move to waiting. BuildRequest waitingRequest = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); Assert.Equal(entry.Request, request); Assert.Null(entry.Result); // Provide the results, move to ready. BuildResult requiredResult = new BuildResult(waitingRequest); requiredResult.AddResultsForTarget("bar", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult); Assert.Equal(BuildRequestEntryState.Ready, entry.State); Assert.Equal(entry.Request, request); Assert.Null(entry.Result); // Continue the build, move to active. results = entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); Assert.Null(entry.Result); Assert.Single(results); Assert.True(results.ContainsKey(requiredResult.NodeRequestId)); Assert.Equal(results[requiredResult.NodeRequestId], requiredResult); // Complete the build, move to completed. BuildResult result = new BuildResult(request); result.AddResultsForTarget("foo", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.Complete(result); Assert.Equal(BuildRequestEntryState.Complete, entry.State); Assert.NotNull(entry.Result); Assert.Equal(entry.Result, result); }
public void TestResultsWithNoMatch1() { BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary <string, string>(), "foo", Array.Empty <string>(), null), "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); Assert.Equal(BuildRequestEntryState.Ready, entry.State); entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest1); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildRequest randomRequest = CreateNewBuildRequest(3, Array.Empty <string>()); BuildResult requiredResult = new BuildResult(randomRequest); requiredResult.AddResultsForTarget("bar", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); }
public void TestNoCompleteToWaiting() { Assert.Throws <InternalErrorException>(() => { BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary <string, string>(), "foo", Array.Empty <string>(), null), "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); Assert.Equal(BuildRequestEntryState.Ready, entry.State); entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); BuildResult requiredResult = new BuildResult(request); requiredResult.AddResultsForTarget("foo", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.Complete(requiredResult); Assert.Equal(BuildRequestEntryState.Complete, entry.State); BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest1); } ); }
public void TestResolveConfiguration() { BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestData data1 = new BuildRequestData("foo", new Dictionary <string, string>(), "foo", new string[0], null); BuildRequestConfiguration config = new BuildRequestConfiguration(1, data1, "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); entry.Continue(); Assert.Equal(entry.State, BuildRequestEntryState.Active); BuildRequest waitingRequest = CreateNewBuildRequest(-1, new string[1] { "bar" }); entry.WaitForResult(waitingRequest); entry.ResolveConfigurationRequest(-1, 2); BuildResult requiredResult = new BuildResult(waitingRequest); requiredResult.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult); Assert.Equal(entry.State, BuildRequestEntryState.Ready); }
public void BuildRequest(NodeLoggingContext context, BuildRequestEntry entry) { Assert.Null(_builderThread); // "Received BuildRequest while one was in progress" _continueEvent = new AutoResetEvent(false); _cancelEvent = new AutoResetEvent(false); _entry = entry; entry.Continue(); _builderThread = new Thread(BuilderThreadProc); _builderThread.Start(); }
public void TestMixedWaitingRequests() { BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestConfiguration config = new BuildRequestConfiguration(1, new BuildRequestData("foo", new Dictionary <string, string>(), "foo", Array.Empty <string>(), null), "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); Assert.Equal(BuildRequestEntryState.Ready, entry.State); entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest1); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildRequest waitingRequest2 = CreateNewBuildRequest(-1, new string[1] { "xor" }); entry.WaitForResult(waitingRequest2); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); Assert.Null(entry.GetRequestsToIssueIfReady()); // "Entry should not be ready to issue because there are unresolved configurations" entry.ResolveConfigurationRequest(-1, 3); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildResult requiredResult1 = new BuildResult(waitingRequest1); requiredResult1.AddResultsForTarget("bar", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult1); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildResult requiredResult2 = new BuildResult(waitingRequest2); requiredResult2.AddResultsForTarget("xor", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult2); Assert.Equal(BuildRequestEntryState.Ready, entry.State); }
/// <summary> /// Build a request entry /// </summary> /// <param name="entry"></param> public void BuildRequest(NodeLoggingContext nodeLoggingContext, BuildRequestEntry entry) { _requestedEntry = entry; if (null == _requestedEntry.RequestConfiguration.Project) { Project mockProject = new Project(XmlReader.Create(new System.IO.StringReader( @"<Project ToolsVersion='4.0' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='t'> </Target> </Project>"))); _requestedEntry.RequestConfiguration.Project = mockProject.CreateProjectInstance(); } _currentProjectDefinition = _testDataProvider[_requestedEntry.Request.ConfigurationId]; _requestedEntry.Continue(); _builderThread = new Thread(BuilderThreadProc); _builderThread.Name = "Builder Thread for Request: " + entry.Request.ConfigurationId.ToString(); _builderThread.Start(); }
public void TestMultipleWaitingRequests() { BuildRequest request = CreateNewBuildRequest(1, new string[1] { "foo" }); BuildRequestData data1 = new BuildRequestData("foo", new Dictionary <string, string>(), "foo", new string[0], null); BuildRequestConfiguration config = new BuildRequestConfiguration(1, data1, "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); entry.Continue(); Assert.Equal(BuildRequestEntryState.Active, entry.State); BuildRequest waitingRequest1 = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest1); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildRequest waitingRequest2 = CreateNewBuildRequest(2, new string[1] { "xor" }); entry.WaitForResult(waitingRequest2); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildResult requiredResult1 = new BuildResult(waitingRequest1); requiredResult1.AddResultsForTarget("bar", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult1); Assert.Equal(BuildRequestEntryState.Waiting, entry.State); BuildResult requiredResult2 = new BuildResult(waitingRequest2); requiredResult2.AddResultsForTarget("xor", BuildResultUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult2); Assert.Equal(BuildRequestEntryState.Ready, entry.State); }
private void BuilderThreadProc() { _entry.RequestConfiguration.Project = CreateStandinProject(); if (ThrowExceptionOnRequest) { BuildResult errorResult = new BuildResult(_entry.Request, new InvalidOperationException("ContinueRequest not received in time.")); _entry.Complete(errorResult); RaiseRequestComplete(_entry); return; } bool completeSuccess = CompleteRequestSuccessfully; if (_cancelEvent.WaitOne(1000)) { BuildResult res = new BuildResult(_entry.Request, new BuildAbortedException()); _entry.Complete(res); RaiseRequestComplete(_entry); return; } for (int i = 0; i < NewRequests.Count; ++i) { OnNewBuildRequests(_entry, NewRequests[i]); WaitHandle[] handles = new WaitHandle[2] { _cancelEvent, _continueEvent }; int evt = WaitHandle.WaitAny(handles, 5000); if (evt == 0) { BuildResult res = new BuildResult(_entry.Request, new BuildAbortedException()); _entry.Complete(res); RaiseRequestComplete(_entry); return; } else if (evt == 1) { IDictionary <int, BuildResult> results = _entry.Continue(); foreach (BuildResult configResult in results.Values) { if (configResult.OverallResult == BuildResultCode.Failure) { completeSuccess = false; break; } } } else { BuildResult errorResult = new BuildResult(_entry.Request, new InvalidOperationException("ContinueRequest not received in time.")); _entry.Complete(errorResult); RaiseRequestComplete(_entry); return; } if (!completeSuccess) { break; } Delay(); } BuildResult result = new BuildResult(_entry.Request); foreach (string target in _entry.Request.Targets) { result.AddResultsForTarget(target, new TargetResult(new TaskItem[1] { new TaskItem("include", _entry.RequestConfiguration.ProjectFullPath) }, completeSuccess ? BuildResultUtilities.GetSuccessResult() : BuildResultUtilities.GetStopWithErrorResult())); } _entry.Complete(result); }
/// <summary> /// Thread to process the build request /// </summary> private void BuilderThreadProc() { bool completeSuccess = true; WaitHandle[] handles = new WaitHandle[2] { cancelEvent, continueEvent }; this.threadStarted.Set(); // Add a request for each of the referenced projects. All we need to do is to make sure that the new project definition for the referenced // project has been added to the host collection FullyQualifiedBuildRequest[] fq = new FullyQualifiedBuildRequest[this.currentProjectDefinition.ChildDefinitions.Count]; int fqCount = 0; foreach (RequestDefinition childDefinition in this.currentProjectDefinition.ChildDefinitions) { BuildRequestConfiguration unresolvedConfig = childDefinition.UnresolvedConfiguration; fq[fqCount++] = new FullyQualifiedBuildRequest(unresolvedConfig, childDefinition.TargetsToBuild, true); } try { // Check to see if there was a cancel before we do anything if (cancelEvent.WaitOne(1, false)) { HandleCancel(); return; } // Submit the build request for the references if we have any if (fqCount > 0) { OnNewBuildRequests(this.requestedEntry, fq); // Wait for all of them to complete till our entry is marked ready int evt = WaitHandle.WaitAny(handles); // If a cancel occurs then we are done. Set the result to an exception if (evt == 0) { HandleCancel(); return; } // If we get a continue then one of the reference has complete. Set the result in the cache only in case of success. // Even though there may have been error - we cannot abandone the loop as there are already // requests in progress which may call back to this thread else if (evt == 1) { IDictionary <int, BuildResult> results = requestedEntry.Continue(); foreach (BuildResult configResult in results.Values) { if (configResult.OverallResult == BuildResultCode.Failure) { completeSuccess = false; } else { this.resultsCache.AddResult(configResult); } } } } // Check to see if there was a cancel we process the final result if (cancelEvent.WaitOne(1, false)) { HandleCancel(); return; } // Simulate execution time for the actual entry if one was specified and if the entry built successfully if (this.currentProjectDefinition.ExecutionTime > 0 && completeSuccess == true) { Thread.Sleep(this.currentProjectDefinition.ExecutionTime); } // Create and send the result BuildResult result = new BuildResult(requestedEntry.Request); // No specific target was asked to build. Return the default result if (requestedEntry.Request.Targets.Count == 0) { result.AddResultsForTarget(RequestDefinition.defaultTargetName, new TargetResult(new TaskItem[1], completeSuccess ? TestUtilities.GetSuccessResult() : TestUtilities.GetStopWithErrorResult())); } else { foreach (string target in requestedEntry.Request.Targets) { result.AddResultsForTarget(target, new TargetResult(new TaskItem[1], completeSuccess ? TestUtilities.GetSuccessResult() : TestUtilities.GetStopWithErrorResult())); } } this.resultsCache.AddResult(result); this.requestedEntry.Complete(result); RaiseRequestComplete(this.requestedEntry); return; } catch (Exception e) { if (this.requestedEntry != null) { string message = String.Format("Test: Unhandeled exception occured: \nMessage: {0} \nStack:\n{1}", e.Message, e.StackTrace); BuildResult errorResult = new BuildResult(this.requestedEntry.Request, new InvalidOperationException(message)); this.requestedEntry.Complete(errorResult); RaiseRequestComplete(this.requestedEntry); } } }