/// <summary> /// Adds the specified build result to the cache /// </summary> /// <param name="result">The result to add.</param> public void AddResult(BuildResult result) { lock (_resultsByConfiguration) { if (_resultsByConfiguration.ContainsKey(result.ConfigurationId)) { if (Object.ReferenceEquals(_resultsByConfiguration[result.ConfigurationId], result)) { // Merging results would be meaningless as we would be merging the object with itself. return; } _resultsByConfiguration[result.ConfigurationId].MergeResults(result); } else { // Note that we are not making a copy here. This is by-design. The TargetBuilder uses this behavior // to ensure that re-entering a project will be able to see all previously built targets and avoid // building them again. if (!_resultsByConfiguration.TryAdd(result.ConfigurationId, result)) { ErrorUtilities.ThrowInternalError("Failed to add result for configuration {0}", result.ConfigurationId); } } } }
private BuildResult MapBuildResult(string project, Microsoft.Build.Execution.BuildResult buildResult) { var escapedProject = EscapingUtilities.Escape(project); return new BuildResult { Project = project, Exception = buildResult.Exception, CircularDependency = buildResult.CircularDependency, ConfigurationId = buildResult.ConfigurationId, GlobalRequestId = buildResult.GlobalRequestId, NodeRequestId = buildResult.NodeRequestId, OverallResult = buildResult.OverallResult, ParentGlobalRequestId = buildResult.ParentGlobalRequestId, ResultsByTarget = new ResultsByTarget(buildResult.ResultsByTarget.ToDictionary(x => x.Key, x => new TargetResult { Name = x.Key, Exception = x.Value.Exception, ResultCode = x.Value.ResultCode, Items = x.Value.Items.Cast<ITaskItem2>().Select( y => new TaskItem( y.EvaluatedIncludeEscaped, escapedProject, ToGeneric(y.CloneCustomMetadataEscaped()))) .ToArray() })) }; }
public void TestSimpleBuildRequest() { BuildRequestConfiguration configuration = CreateTestProject(1); try { TestTargetBuilder targetBuilder = (TestTargetBuilder)_host.GetComponent(BuildComponentType.TargetBuilder); IConfigCache configCache = (IConfigCache)_host.GetComponent(BuildComponentType.ConfigCache); configCache.AddConfiguration(configuration); BuildRequest request = CreateNewBuildRequest(1, new string[1] { "target1" }); BuildRequestEntry entry = new BuildRequestEntry(request, configuration); BuildResult result = new BuildResult(request); result.AddResultsForTarget("target1", GetEmptySuccessfulTargetResult()); targetBuilder.SetResultsToReturn(result); _requestBuilder.BuildRequest(GetNodeLoggingContext(), entry); WaitForEvent(_buildRequestCompletedEvent, "Build Request Completed"); Assert.Equal(BuildRequestEntryState.Complete, entry.State); Assert.Equal(entry, _buildRequestCompleted_Entry); Assert.Equal(BuildResultCode.Success, _buildRequestCompleted_Entry.Result.OverallResult); } finally { DeleteTestProject(configuration); } }
public void SetUp() { LoggingServiceFactory loggingFactory = new LoggingServiceFactory(LoggerMode.Synchronous, 1); _loggingService = loggingFactory.CreateInstance(BuildComponentType.LoggingService) as LoggingService; _customLogger = new MyCustomLogger(); _mockHost = new MockHost(); _mockHost.LoggingService = _loggingService; _loggingService.RegisterLogger(_customLogger); _elementLocation = ElementLocation.Create("MockFile", 5, 5); BuildRequest buildRequest = new BuildRequest(1 /* submissionId */, 1, 1, new List<string>(), null, BuildEventContext.Invalid, null); BuildRequestConfiguration configuration = new BuildRequestConfiguration(1, new BuildRequestData("Nothing", new Dictionary<string, string>(), "4.0", new string[0], null), "2.0"); configuration.Project = new ProjectInstance(ProjectRootElement.Create()); BuildRequestEntry entry = new BuildRequestEntry(buildRequest, configuration); BuildResult buildResult = new BuildResult(buildRequest, false); buildResult.AddResultsForTarget("Build", new TargetResult(new TaskItem[] { new TaskItem("IamSuper", configuration.ProjectFullPath) }, TestUtilities.GetSkippedResult())); _mockRequestCallback = new MockIRequestBuilderCallback(new BuildResult[] { buildResult }); entry.Builder = (IRequestBuilder)_mockRequestCallback; _taskHost = new TaskHost(_mockHost, entry, _elementLocation, null /*Dont care about the callback either unless doing a build*/); _taskHost.LoggingContext = new TaskLoggingContext(_loggingService, BuildEventContext.Invalid); }
/// <summary> /// Checks that a SonarQubeSetting does not exist /// </summary> public static void AssertAnalysisSettingDoesNotExist(BuildResult actualResult, string settingName) { Assert.IsNotNull(actualResult.ProjectStateAfterBuild, "Test error: ProjectStateAfterBuild should not be null"); IEnumerable<ProjectItemInstance> matches = actualResult.ProjectStateAfterBuild.GetItemsByItemTypeAndEvaluatedInclude(BuildTaskConstants.SettingItemName, settingName); Assert.AreEqual(0, matches.Count(), "Not expected SonarQubeSetting with include value of '{0}' to exist. Actual occurences: {1}", settingName, matches.Count()); }
public void TestConstructorBad() { Assert.Throws<InternalErrorException>(() => { BuildResult result = new BuildResult(null); } ); }
public void TestConfigurationId() { BuildRequest request = CreateNewBuildRequest(-1, new string[0]); BuildResult result = new BuildResult(request); Assert.AreEqual(-1, result.ConfigurationId); BuildRequest request2 = CreateNewBuildRequest(1, new string[0]); BuildResult result2 = new BuildResult(request2); Assert.AreEqual(1, result2.ConfigurationId); }
/// <summary> /// Checks that building the specified target produced the expected result. /// </summary> public static void AssertExpectedTargetOutput(BuildResult result, string target, BuildResultCode resultCode) { DumpTargetResult(result, target); TargetResult targetResult; if (!result.ResultsByTarget.TryGetValue(target, out targetResult)) { Assert.Inconclusive(@"Could not find result for target ""{0}""", target); } Assert.AreEqual<BuildResultCode>(resultCode, result.OverallResult, "Unexpected build result"); }
public void TestAddAndRetrieveResults() { ResultsCache cache = new ResultsCache(); BuildRequest request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "testTarget" }, null, BuildEventContext.Invalid, null); BuildResult result = new BuildResult(request); result.AddResultsForTarget("testTarget", TestUtilities.GetEmptyFailingTargetResult()); cache.AddResult(result); BuildResult retrievedResult = cache.GetResultForRequest(request); Assert.True(AreResultsIdentical(result, retrievedResult)); }
// FIXME: // While we are not faced to implement those features, there are some modern task execution requirements. // // This will have to be available for "out of process" nodes (see NodeAffinity). // NodeAffinity is set per project file at BuildManager.HostServices. // When NodeAffinity is set to OutOfProc, it should probably launch different build host // that runs separate build tasks. (.NET has MSBuildTaskHost.exe which I guess is about that.) // // Also note that the complete implementation has to support LoadInSeparateAppDomainAttribute // (which is most likely derived from AppDomainIsolatedBuildTask) that marks a task to run // in separate AppDomain. // public void BuildProject (Func<bool> checkCancel, BuildResult result, ProjectInstance project, IEnumerable<string> targetNames, IDictionary<string,string> globalProperties, IDictionary<string,string> targetOutputs, string toolsVersion) { if (toolsVersion == null) throw new ArgumentNullException ("toolsVersion"); var parameters = submission.BuildManager.OngoingBuildParameters; var toolset = parameters.GetToolset (toolsVersion); if (toolset == null) throw new InvalidOperationException (string.Format ("Toolset version '{0}' was not resolved to valid toolset", toolsVersion)); LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using Toolset version {0}.", toolsVersion), null, null, MessageImportance.Low)); var buildTaskFactory = new BuildTaskFactory (BuildTaskDatabase.GetDefaultTaskDatabase (toolset), new BuildTaskDatabase (this, submission.BuildRequest.ProjectInstance)); BuildProject (new InternalBuildArguments () { CheckCancel = checkCancel, Result = result, Project = project, TargetNames = targetNames, GlobalProperties = globalProperties, TargetOutputs = targetOutputs, ToolsVersion = toolsVersion, BuildTaskFactory = buildTaskFactory }); }
/// <summary> /// Checks that the expected number of ItemType entries exist /// </summary> public static void AssertExpectedItemGroupCount(BuildResult actualResult, string itemType, int expectedCount) { Assert.IsNotNull(actualResult.ProjectStateAfterBuild, "Test error: ProjectStateAfterBuild should not be null"); IEnumerable<ProjectItemInstance> matches = actualResult.ProjectStateAfterBuild.GetItems(itemType); BuildUtilities.LogMessage("Analyzers:"); foreach(ProjectItemInstance item in matches) { BuildUtilities.LogMessage("\t{0}", item.EvaluatedInclude); } Assert.AreEqual(expectedCount, matches.Count(), "Unexpected number of '{0}' items", itemType); }
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", new string[0], null), "2.0"); BuildRequestEntry entry = new BuildRequestEntry(request, config); Assert.AreEqual(entry.State, BuildRequestEntryState.Ready); Assert.AreEqual(entry.Request, request); Assert.IsNull(entry.Result); // Move to active. Should not be any results yet. IDictionary<int, BuildResult> results = entry.Continue(); Assert.AreEqual(entry.State, BuildRequestEntryState.Active); Assert.IsNull(entry.Result); Assert.IsNull(results); // Wait for results, move to waiting. BuildRequest waitingRequest = CreateNewBuildRequest(2, new string[1] { "bar" }); entry.WaitForResult(waitingRequest); Assert.AreEqual(entry.State, BuildRequestEntryState.Waiting); Assert.AreEqual(entry.Request, request); Assert.IsNull(entry.Result); // Provide the results, move to ready. BuildResult requiredResult = new BuildResult(waitingRequest); requiredResult.AddResultsForTarget("bar", TestUtilities.GetEmptySucceedingTargetResult()); entry.ReportResult(requiredResult); Assert.AreEqual(entry.State, BuildRequestEntryState.Ready); Assert.AreEqual(entry.Request, request); Assert.IsNull(entry.Result); // Continue the build, move to active. results = entry.Continue(); Assert.AreEqual(entry.State, BuildRequestEntryState.Active); Assert.IsNull(entry.Result); Assert.AreEqual(results.Count, 1); Assert.IsTrue(results.ContainsKey(requiredResult.NodeRequestId)); Assert.AreEqual(results[requiredResult.NodeRequestId], requiredResult); // Complete the build, move to completed. BuildResult result = new BuildResult(request); result.AddResultsForTarget("foo", TestUtilities.GetEmptySucceedingTargetResult()); entry.Complete(result); Assert.AreEqual(entry.State, BuildRequestEntryState.Complete); Assert.IsNotNull(entry.Result); Assert.AreEqual(entry.Result, result); }
public void TestAddAndRetrieveResultsByConfiguration() { ResultsCache cache = new ResultsCache(); BuildRequest request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "testTarget" }, null, BuildEventContext.Invalid, null); BuildResult result = new BuildResult(request); result.AddResultsForTarget("testTarget", TestUtilities.GetEmptyFailingTargetResult()); cache.AddResult(result); request = new BuildRequest(1 /* submissionId */, 0, 1, new string[1] { "otherTarget" }, null, BuildEventContext.Invalid, null); result = new BuildResult(request); result.AddResultsForTarget("otherTarget", TestUtilities.GetEmptySucceedingTargetResult()); cache.AddResult(result); BuildResult retrievedResult = cache.GetResultsForConfiguration(1); Assert.True(retrievedResult.HasResultsForTarget("testTarget")); Assert.True(retrievedResult.HasResultsForTarget("otherTarget")); }
internal BuildResult InternalExecute () { BuildResult = new BuildResult () { SubmissionId = SubmissionId }; try { var engine = new BuildEngine4 (this); string toolsVersion = request.ExplicitlySpecifiedToolsVersion ?? request.ProjectInstance.ToolsVersion ?? BuildManager.OngoingBuildParameters.DefaultToolsVersion; var outputs = new Dictionary<string,string> (); engine.BuildProject (() => is_canceled, BuildResult, request.ProjectInstance, request.TargetNames, BuildManager.OngoingBuildParameters.GlobalProperties, outputs, toolsVersion); } catch (Exception ex) { BuildResult.Exception = ex; BuildResult.OverallResult = BuildResultCode.Failure; } is_completed = true; if (callback != null) callback (this); wait_handle.Set (); return BuildResult; }
public void MergeResults (BuildResult results) { if (ConfigurationId != results.ConfigurationId) throw new InvalidOperationException ("Argument BuildResults have inconsistent ConfigurationId."); if (GlobalRequestId != results.GlobalRequestId) throw new InvalidOperationException ("Argument BuildResults have inconsistent GlobalRequestId."); if (NodeRequestId != results.NodeRequestId) throw new InvalidOperationException ("Argument BuildResults have inconsistent NodeRequestId."); if (ParentGlobalRequestId != results.ParentGlobalRequestId) throw new InvalidOperationException ("Argument BuildResults have inconsistent ParentGlobalRequestId."); if (SubmissionId != results.SubmissionId) throw new InvalidOperationException ("Argument BuildResults have inconsistent SubmissionId."); CircularDependency |= results.CircularDependency; Exception = Exception ?? results.Exception; foreach (var p in results.ResultsByTarget) ResultsByTarget.Add (p.Key, p.Value); }
/// <summary> /// Writes the build and target output to the output stream /// </summary> public static void DumpTargetResult(BuildResult result, string target) { if (result == null) { throw new ArgumentNullException("result"); } BuildUtilities.LogMessage("Overall build result: {0}", result.OverallResult.ToString()); TargetResult targetResult; if (!result.ResultsByTarget.TryGetValue(target, out targetResult)) { BuildUtilities.LogMessage(@"Could not find result for target ""{0}""", target); } else { BuildUtilities.LogMessage(@"Results for target ""{0}""", target); BuildUtilities.LogMessage("\tTarget exception: {0}", targetResult.Exception == null ? "{null}" : targetResult.Exception.Message); BuildUtilities.LogMessage("\tTarget result: {0}", targetResult.ResultCode.ToString()); } }
/// <summary> /// Checks whether there is a single "SonarQubeSetting" item with the expected name and setting value /// </summary> public static void AssertExpectedAnalysisSetting(BuildResult actualResult, string settingName, string expectedValue) { /* The equivalent XML would look like this: <ItemGroup> <SonarQubeSetting Include="settingName"> <Value>expectedValue</Value </SonarQubeSetting> </ItemGroup> */ Assert.IsNotNull(actualResult.ProjectStateAfterBuild, "Test error: ProjectStateAfterBuild should not be null"); IEnumerable<ProjectItemInstance> matches = actualResult.ProjectStateAfterBuild.GetItemsByItemTypeAndEvaluatedInclude(BuildTaskConstants.SettingItemName, settingName); Assert.AreNotEqual(0, matches.Count(), "Expected SonarQubeSetting with include value of '{0}' does not exist", settingName); Assert.AreEqual(1, matches.Count(), "Only expecting one SonarQubeSetting with include value of '{0}' to exist", settingName); ProjectItemInstance item = matches.Single(); string value = item.GetMetadataValue(BuildTaskConstants.SettingValueMetadataName); Assert.AreEqual(expectedValue, value, "SonarQubeSetting with include value '{0}' does not have the expected value", settingName); }
public void Clone() { BuildRequest request = CreateNewBuildRequest(1, new string[0]); BuildResult result1 = new BuildResult(request); result1.ResultsByTarget.Add("FOO", TestUtilities.GetEmptySucceedingTargetResult()); Assert.IsTrue(result1.ResultsByTarget.ContainsKey("foo")); // test comparer BuildResult result2 = result1.Clone(); result1.ResultsByTarget.Add("BAR", TestUtilities.GetEmptySucceedingTargetResult()); Assert.IsTrue(result1.ResultsByTarget.ContainsKey("foo")); // test comparer Assert.IsTrue(result1.ResultsByTarget.ContainsKey("bar")); Assert.AreEqual(result1.SubmissionId, result2.SubmissionId); Assert.AreEqual(result1.ConfigurationId, result2.ConfigurationId); Assert.AreEqual(result1.GlobalRequestId, result2.GlobalRequestId); Assert.AreEqual(result1.ParentGlobalRequestId, result2.ParentGlobalRequestId); Assert.AreEqual(result1.NodeRequestId, result2.NodeRequestId); Assert.AreEqual(result1.CircularDependency, result2.CircularDependency); Assert.AreEqual(result1.ResultsByTarget["foo"], result2.ResultsByTarget["foo"]); Assert.AreEqual(result1.OverallResult, result2.OverallResult); }
public void BuildAndAnalyze() { var globalProps = new Dictionary<string, string> { {"VisualStudioVersion","12.0"} }; pc = new ProjectCollection(globalProps); var diagLogger = new DiagnosticXmlLogger(this); diagLogger.LogFile = _logFilepath; project = pc.LoadProject(_projectFilepath, "12.0"); projInst = project.CreateProjectInstance(); buildManager = new BuildManager(); var buildParams = new BuildParameters(); buildParams.Loggers = new ILogger[] { diagLogger }; buildManager.BeginBuild(buildParams); var brd = new BuildRequestData(projInst, _targets, null, BuildRequestDataFlags.ReplaceExistingProjectInstance); submission = buildManager.PendBuildRequest(brd); buildResult = submission.Execute(); buildManager.EndBuild(); }
/// <summary> /// Logs the project started/finished pair for projects which are skipped entirely because all /// of their results are available in the cache. /// </summary> internal void LogRequestHandledFromCache(BuildRequest request, BuildRequestConfiguration configuration, BuildResult result) { ProjectLoggingContext projectLoggingContext = LogProjectStarted(request, configuration); // When pulling a request from the cache, we want to make sure we log a task skipped message for any targets which // were used to build the request including default and inital targets. foreach (string target in configuration.GetTargetsUsedToBuildRequest(request)) { projectLoggingContext.LogComment ( MessageImportance.Low, result[target].ResultCode == TargetResultCode.Failure ? "TargetAlreadyCompleteFailure" : "TargetAlreadyCompleteSuccess", target ); if (result[target].ResultCode == TargetResultCode.Failure) { break; } } projectLoggingContext.LogProjectFinished(result.OverallResult == BuildResultCode.Success); }
private void AssertExpectedAnalyzersExists(BuildResult result, params string[] analyzerFilePaths) { this.DumpAnalyzerLists(result, analyzerFilePaths); foreach (string filePath in analyzerFilePaths) { BuildAssertions.AssertSingleItemExists(result, TargetProperties.AnalyzerItemType, filePath); } BuildAssertions.AssertExpectedItemGroupCount(result, TargetProperties.AnalyzerItemType, analyzerFilePaths.Length); }
private static void AssertExpectedAnalysisProperties(BuildResult result, string expectedErrorLog, string expectedResolvedRuleset) { // Check the ruleset and error log are not set BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, TargetProperties.ErrorLog, expectedErrorLog); BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, TargetProperties.ResolvedCodeAnalysisRuleset, expectedResolvedRuleset); }
private static void AssertCodeAnalysisIsDisabled(BuildResult result) { // Check the ruleset and error log are not set AssertExpectedAnalysisProperties(result, string.Empty, string.Empty); }
private string ResolveTargetPath(BuildResult result) { string targetPath = null; TargetResult targetResult; if (result.ResultsByTarget.TryGetValue("Build", out targetResult)) { if (targetResult.Items.Any()) { targetPath = targetResult.Items.First().ItemSpec; } } return targetPath ?? ResolveTargetPath(); }
/// <summary> /// This reports a result for a request on which this entry was waiting. /// PERF: Once we have fixed up all the result reporting, we can probably /// optimize this. See the comment in BuildRequestEngine.ReportBuildResult. /// </summary> /// <param name="result">The result for the request.</param> public void ReportResult(BuildResult result) { lock (_dataMonitor) { ErrorUtilities.VerifyThrowArgumentNull(result, "result"); ErrorUtilities.VerifyThrow(_state == BuildRequestEntryState.Waiting || _outstandingRequests == null, "Entry must be in the Waiting state to report results, or we must have flushed our requests due to an error. Config: {0} State: {1} Requests: {2}", _requestConfiguration.ConfigurationId, _state, _outstandingRequests != null); // If the matching request is in the issue list, remove it so we don't try to ask for it to be built. if (_requestsToIssue != null) { for (int i = 0; i < _requestsToIssue.Count; i++) { if (_requestsToIssue[i].NodeRequestId == result.NodeRequestId) { _requestsToIssue.RemoveAt(i); if (_requestsToIssue.Count == 0) { _requestsToIssue = null; } break; } } } // If this result is for the request we were blocked on locally (target re-entrancy) clear out our blockage. bool addResults = false; if (_blockingGlobalRequestId == result.GlobalRequestId) { _blockingGlobalRequestId = BuildRequest.InvalidGlobalRequestId; if (_outstandingRequests == null) { ErrorUtilities.VerifyThrow(result.CircularDependency, "Received result for target in progress and it wasn't a circular dependency error."); addResults = true; } } // We could be in the waiting state but waiting on configurations instead of results, or we received a circular dependency // result, which blows away everything else we were waiting on. if (_outstandingRequests != null) { _outstandingRequests.Remove(result.NodeRequestId); // If we wish to implement behavior where we stop building after the first failing request, then check for // overall results being failure rather than just circular dependency. Sync with BasicScheduler.ReportResult and // BasicScheduler.ReportRequestBlocked. if (result.CircularDependency || (_outstandingRequests.Count == 0 && (_unresolvedConfigurations == null || _unresolvedConfigurations.Count == 0))) { _outstandingRequests = null; _unresolvedConfigurations = null; // If we are in the middle of IssueBuildRequests and collecting requests (and cached results), one of those results // was a failure. As a result, this entry will fail, and submitting further requests from it would be pointless. _requestsToIssue = null; _unresolvedConfigurationsToIssue = null; } addResults = true; } if (addResults) { // Update the local results record _outstandingResults = _outstandingResults ?? new Dictionary<int, BuildResult>(); ErrorUtilities.VerifyThrow(!_outstandingResults.ContainsKey(result.NodeRequestId), "Request already contains results."); _outstandingResults.Add(result.NodeRequestId, result); } // If we are out of outstanding requests, we are ready to continue. if (_outstandingRequests == null && _unresolvedConfigurations == null && _blockingGlobalRequestId == BuildRequest.InvalidGlobalRequestId) { ChangeState(BuildRequestEntryState.Ready); } } }
/// <summary> /// Constructs a new build result with existing results, but associated with the specified request. /// </summary> /// <param name="request">The build request with which these results should be associated.</param> /// <param name="existingResults">The existing results, if any.</param> /// <param name="targetNames">The list of target names that are the subset of results that should be returned.</param> /// <param name="additionalTargetsToCheck">The additional targets that need to be taken into account when computing the overall result, if any.</param> /// <param name="exception">The exception, if any</param> internal BuildResult(BuildRequest request, BuildResult existingResults, string[] targetNames, List <string> additionalTargetsToCheck, Exception exception) { ErrorUtilities.VerifyThrow(request != null, "Must specify a request."); _submissionId = request.SubmissionId; _configurationId = request.ConfigurationId; _globalRequestId = request.GlobalRequestId; _parentGlobalRequestId = request.ParentGlobalRequestId; _nodeRequestId = request.NodeRequestId; _circularDependency = false; if (existingResults == null) { _requestException = exception; _resultsByTarget = CreateTargetResultDictionary(0); _baseOverallResult = true; } else { _requestException = exception ?? existingResults._requestException; _resultsByTarget = targetNames == null ? existingResults._resultsByTarget : CreateTargetResultDictionaryWithContents(existingResults, targetNames); if (existingResults.OverallResult == BuildResultCode.Success || (additionalTargetsToCheck == null || additionalTargetsToCheck.Count == 0)) { // If we know for a fact that all of the existing results succeeded, then by definition we'll have // succeeded too. Alternately, if we don't have any additional targets to check, then we want the // overall result to reflect only the targets included in this result, which the OverallResult // property already does -- so just default to true in that case as well. _baseOverallResult = true; } else { // If the existing result is a failure, then we need to determine whether the targets we are // specifically interested in contributed to that failure or not. If they did not, then this // result should be sucessful even though the result it is based on failed. // // For the most part, this is taken care of for us because any dependent targets that fail also // mark their parent targets (up to and including the entrypoint target) as failed. However, // there is one case in which this is not true: if the entrypoint target has AfterTargets that // fail, then as far as the entrypoint target knows when it is executing, it has succeeded. The // failure doesn't come until after. On the other hand, we don't want to actually include the // AfterTarget results in the build result itself if the user hasn't asked for them. // // So in the case where there are AfterTargets, we will check them for failure so that we can // make sure the overall success/failure result is correct, but not actually add their contents // to the new result. _baseOverallResult = true; foreach (string additionalTarget in additionalTargetsToCheck) { if (existingResults.ResultsByTarget.TryGetValue(additionalTarget, out TargetResult targetResult)) { if (targetResult.ResultCode == TargetResultCode.Failure && !targetResult.TargetFailureDoesntCauseBuildFailure) { _baseOverallResult = false; break; } } } } } }
internal BuildResult(MSB.Execution.BuildResult result, MSB.Execution.ProjectInstance instance) { this.Result = result; this.Instance = instance; }
/// <summary> /// Completes this request. /// </summary> public void Complete(BuildResult result) { VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Ready, SchedulableRequestState.Executing, SchedulableRequestState.Unscheduled }); ErrorUtilities.VerifyThrow(_state != SchedulableRequestState.Ready || result.CircularDependency, "Request can only be Completed from the Ready state if the result indicates a circular dependency occurred."); ErrorUtilities.VerifyThrow(_requestsWeAreBlockedBy.Count == 0, "We can't be complete if we are still blocked on requests."); // Any requests we were blocking we will no longer be blocking. List<SchedulableRequest> requestsToUnblock = new List<SchedulableRequest>(_requestsWeAreBlocking); foreach (SchedulableRequest requestWeAreBlocking in requestsToUnblock) { requestWeAreBlocking.UnblockWithResult(result); } ChangeToState(SchedulableRequestState.Completed); }
private void DumpAnalyzerLists(BuildResult actualResult, string[] expected) { this.TestContext.WriteLine(""); this.TestContext.WriteLine("Dumping analyzer list: expected"); foreach (string analyzer in expected) { this.TestContext.WriteLine("\t{0}", analyzer); } this.TestContext.WriteLine(""); this.TestContext.WriteLine(""); this.TestContext.WriteLine("Dumping analyzer list: actual"); foreach (ProjectItemInstance analyzer in actualResult.ProjectStateAfterBuild.GetItems(TargetProperties.AnalyzerItemType)) { this.TestContext.WriteLine("\t{0}", analyzer.EvaluatedInclude); } this.TestContext.WriteLine(""); }
/// <summary> /// Creates a build request entry from a build request. /// </summary> /// <param name="request">The originating build request.</param> /// <param name="requestConfiguration">The build request configuration.</param> internal BuildRequestEntry(BuildRequest request, BuildRequestConfiguration requestConfiguration) { ErrorUtilities.VerifyThrowArgumentNull(request, "request"); ErrorUtilities.VerifyThrowArgumentNull(requestConfiguration, "requestConfiguration"); ErrorUtilities.VerifyThrow(requestConfiguration.ConfigurationId == request.ConfigurationId, "Configuration id mismatch"); _dataMonitor = new Object(); _request = request; _requestConfiguration = requestConfiguration; _blockingGlobalRequestId = BuildRequest.InvalidGlobalRequestId; _completedResult = null; ChangeState(BuildRequestEntryState.Ready); }
/// <summary> /// Constructs a new build result with existing results, but associated with the specified request. /// </summary> /// <param name="request">The build request with which these results should be associated.</param> /// <param name="existingResults">The existing results, if any.</param> /// <param name="exception">The exception, if any</param> internal BuildResult(BuildRequest request, BuildResult existingResults, Exception exception) : this(request, existingResults, null, null, exception) { }
/// <summary> /// Marks this entry as complete and sets the final results. /// </summary> /// <param name="result">The result of the build.</param> public void Complete(BuildResult result) { lock (_dataMonitor) { ErrorUtilities.VerifyThrowArgumentNull(result, "result"); ErrorUtilities.VerifyThrow(_completedResult == null, "Entry already Completed."); // If this request is determined to be a success, then all outstanding items must have been taken care of // and it must be in the correct state. It can complete unsuccessfully for a variety of reasons in a variety // of states. if (result.OverallResult == BuildResultCode.Success) { ErrorUtilities.VerifyThrow(_state == BuildRequestEntryState.Active, "Entry must be active before it can be Completed successfully. Config: {0} State: {1}", _requestConfiguration.ConfigurationId, _state); ErrorUtilities.VerifyThrow(_unresolvedConfigurations == null, "Entry must not have any unresolved configurations."); ErrorUtilities.VerifyThrow(_outstandingRequests == null, "Entry must have no outstanding requests."); ErrorUtilities.VerifyThrow(_outstandingResults == null, "Results must be consumed before request may be completed."); } _completedResult = result; ChangeState(BuildRequestEntryState.Complete); } }
public void AddResult(BuildResult result) { CurrentCache.AddResult(result); }
/// <summary> /// Indicates that there are results which can be used to unblock this request. Updates the relationships between requests. /// </summary> public void UnblockWithResult(BuildResult result) { VerifyOneOfStates(new SchedulableRequestState[] { SchedulableRequestState.Blocked, SchedulableRequestState.Unscheduled }); ErrorUtilities.VerifyThrowArgumentNull(result, "result"); BlockingRequestKey key = new BlockingRequestKey(result); DisconnectRequestWeAreBlockedBy(key); _activeTargetsWhenBlocked = null; }
public static BuildResult Build( string solutionFile, string buildConfiguration = null, string buildPlatform = null, string buildTarget = "Build", string logVerbosity = null, bool?inProcess = null ) { bool defaultInProcess = Debugger.IsAttached; if (!inProcess.GetValueOrDefault(defaultInProcess)) { var argsDict = new Dictionary <string, object> { { "solutionFile", solutionFile }, { "buildConfiguration", buildConfiguration }, { "buildPlatform", buildPlatform }, { "buildTarget", buildTarget }, { "logVerbosity", logVerbosity } }; return(OutOfProcessBuild(argsDict)); } string configString = String.Format("{0}|{1}", buildConfiguration ?? "<default>", buildPlatform ?? "<default>"); if ((buildConfiguration ?? buildPlatform) != null) { Console.Error.WriteLine("// Running target '{2}' of '{0}' ({1}) ...", JSIL.Compiler.Program.ShortenPath(solutionFile), configString, buildTarget); } else { Console.Error.WriteLine("// Running target '{1}' of '{0}' ...", JSIL.Compiler.Program.ShortenPath(solutionFile), buildTarget); } var pc = new ProjectCollection(); var parms = new BuildParameters(pc); var globalProperties = new Dictionary <string, string>(); var hostServices = new HostServices(); var eventRecorder = new BuildEventRecorder(); LoggerVerbosity _logVerbosity; if ((logVerbosity == null) || !Enum.TryParse(logVerbosity, out _logVerbosity)) { _logVerbosity = LoggerVerbosity.Quiet; } parms.Loggers = new ILogger[] { new ConsoleLogger(_logVerbosity), eventRecorder }; var manager = BuildManager.DefaultBuildManager; Console.Error.Write("// Generating MSBuild projects for solution '{0}'...", Path.GetFileName(solutionFile)); // Begin a fake build so the manager has a logger available. manager.BeginBuild(parms); var projects = ParseSolutionFile( solutionFile, buildConfiguration, buildPlatform, globalProperties, manager ); manager.EndBuild(); Console.Error.WriteLine(" {0} project(s) generated.", projects.Length); if (File.ReadAllText(solutionFile).Contains("ProjectSection(ProjectDependencies)")) { Console.Error.WriteLine("// WARNING: Your solution file contains project dependencies. MSBuild ignores these, so your build may fail. If it does, try building it in Visual Studio first to resolve the dependencies."); } var allItemsBuilt = new List <BuiltItem>(); var resultFiles = new HashSet <string>(); foreach (var project in projects) { // Save out the generated msbuild project for each solution, to aid debugging. try { project.ToProjectRootElement().Save(project.FullPath, Encoding.UTF8); } catch (Exception exc) { Console.Error.WriteLine("// Failed to save generated project '{0}': {1}", Path.GetFileName(project.FullPath), exc.Message); } } foreach (var project in projects) { Console.Error.WriteLine("// Building project '{0}'...", project.FullPath); var request = new BuildRequestData( project, new string[] { buildTarget }, hostServices, BuildRequestDataFlags.None ); Microsoft.Build.Execution.BuildResult result = null; try { result = manager.Build(parms, request); } catch (Exception exc) { Console.Error.WriteLine("// Compilation failed: {0}", exc.Message); continue; } allItemsBuilt.AddRange(ExtractChildProjectResults(manager)); foreach (var kvp in result.ResultsByTarget) { var targetResult = kvp.Value; if ((targetResult.Exception != null) || (targetResult.ResultCode == TargetResultCode.Failure)) { string errorMessage = "Unknown error"; if (targetResult.Exception != null) { errorMessage = targetResult.Exception.Message; } Console.Error.WriteLine("// Compilation failed for target '{0}': {1}", kvp.Key, errorMessage); } } } // ResultsByTarget doesn't reliably produce all the output executables, so we must // extract them by hand. foreach (var builtItem in allItemsBuilt) { if (builtItem.TargetName != "Build") { continue; } if (!File.Exists(builtItem.OutputPath)) { Console.Error.WriteLine("// Ignoring nonexistent build output '" + Path.GetFileName(builtItem.OutputPath) + "'."); continue; } var extension = Path.GetExtension(builtItem.OutputPath).ToLowerInvariant(); switch (extension) { case ".exe": case ".dll": resultFiles.Add(builtItem.OutputPath); break; default: Console.Error.WriteLine("// Ignoring build output '" + Path.GetFileName(builtItem.OutputPath) + "' due to unknown file type."); break; } } return(new BuildResult( Path.GetFullPath(solutionFile), resultFiles.ToArray(), eventRecorder.ProjectsById.Values.ToArray(), eventRecorder.TargetFiles.ToArray(), allItemsBuilt.ToArray() )); }
/// <summary> /// Constructor over a result. /// </summary> public BlockingRequestKey(BuildResult result) { _globalRequestId = result.GlobalRequestId; _nodeRequestId = result.NodeRequestId; }
/// <summary> /// Creates the target result dictionary and populates it with however many target results are /// available given the list of targets passed. /// </summary> private ConcurrentDictionary <string, TargetResult> CreateTargetResultDictionaryWithContents(BuildResult existingResults, string[] targetNames) { var resultsByTarget = CreateTargetResultDictionary(targetNames.Length); foreach (string target in targetNames) { TargetResult targetResult; if (existingResults.ResultsByTarget.TryGetValue(target, out targetResult)) { resultsByTarget[target] = targetResult; } } return(resultsByTarget); }