public void ProjectsInQueueShouldNotIntegrateIfQueueIsLocked() { // ensure we have the correct setup for testing string[] queues = integrationQueues.GetQueueNames(); integrationQueues[queues[0]].Configuration.LockQueueNames = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0},{1}", queues[1], queues[2]); integrationQueues[queues[1]].Configuration.LockQueueNames = queues[0]; integrationQueues[queues[2]].Configuration.LockQueueNames = queues[0]; // now lock one of the queues and add projects to it IDisposable lock1; Assert.IsTrue(integrationQueues[queues[0]].TryLock(out lock1)); project1Mock.SetupResult("QueueName", queues[1]); project1Mock.SetupResult("QueuePriority", 1); queueNotifier1Mock.Expect("NotifyEnteringIntegrationQueue"); integrationQueueReplace.Enqueue(integrationQueueItem1); Assert.IsNull(integrationQueueReplace.GetNextRequest((IProject)project1Mock.MockInstance), "Expected no next request, as queue is locked"); lock1.Dispose(); IntegrationRequest next = integrationQueueReplace.GetNextRequest((IProject)project1Mock.MockInstance); Assert.IsNotNull(next, "Expected next request as queue lock has been released"); }
public void GetNextRequestIsNullWithNothingOnQueue() { IntegrationRequest ir = integrationQueueUseFirst.GetNextRequest((IProject)project1Mock.MockInstance); Assert.IsNull(ir); VerifyAll(); }
private bool Integrate() { bool ran = false; while (integrationQueue.IsBlocked) { Thread.Sleep(200); } IntegrationRequest ir = integrationQueue.GetNextRequest(project); if (ir != null && IsRunning) { IDisposable queueLock; if (!integrationQueue.TryLock(out queueLock)) { return(false); } using (queueLock) { // Check to see if this integration request should proceed - Extension point IntegrationStartedEventArgs.EventResult eventResult = FireIntegrationStarted(ir); switch (eventResult) { case IntegrationStartedEventArgs.EventResult.Continue: Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Project: '{0}' is first in queue: '{1}' and shall start integration.", project.Name, project.QueueName)); IntegrationStatus status = IntegrationStatus.Unknown; IIntegrationResult result = new IntegrationResult(); ran = true; try { ir.PublishOnSourceControlException = (AmountOfSourceControlExceptions == project.MaxSourceControlRetries) || (project.SourceControlErrorHandling == ThoughtWorks.CruiseControl.Core.Sourcecontrol.Common.SourceControlErrorHandlingPolicy.ReportEveryFailure); result = project.Integrate(ir); if (result != null) { status = result.Status; } } catch { status = IntegrationStatus.Exception; throw; } finally { RemoveCompletedRequestFromQueue(); // Tell any extensions that an integration has completed FireIntegrationCompleted(ir, status); // handle post build : check what to do if source control errors occured if (result != null) { if (result.SourceControlError != null) { AmountOfSourceControlExceptions++; } else { AmountOfSourceControlExceptions = 0; } } if ((AmountOfSourceControlExceptions > project.MaxSourceControlRetries) && (project.SourceControlErrorHandling == ThoughtWorks.CruiseControl.Core.Sourcecontrol.Common.SourceControlErrorHandlingPolicy.ReportOnEveryRetryAmount)) { AmountOfSourceControlExceptions = 0; } if ((AmountOfSourceControlExceptions > project.MaxSourceControlRetries) && project.StopProjectOnReachingMaxSourceControlRetries) { Stopped(); } } break; case IntegrationStartedEventArgs.EventResult.Delay: // Log that the request has been cancelled and delay until the request is cleared - otherwise // stuck in an endless loop until the extensions allow the request through Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "An external extension has delayed an integration - project '{0}' on queue '{1}'", project.Name, project.QueueName)); while (FireIntegrationStarted(ir) == IntegrationStartedEventArgs.EventResult.Delay) { Thread.Sleep(1000); } break; case IntegrationStartedEventArgs.EventResult.Cancel: Log.Info(string.Format(System.Globalization.CultureInfo.CurrentCulture, "An external extension has cancelled an integration - project '{0}' on queue '{1}'", project.Name, project.QueueName)); RemoveCompletedRequestFromQueue(); FireIntegrationCompleted(ir, IntegrationStatus.Cancelled); break; } } } else { PollTriggers(); // If a build is queued for this project we need to hang around until either: // - the build gets started by reaching it's turn on the queue // - the build gets cancelled from the queue // - the thread gets killed // However, if the queue is blocked, do not hang around - we need to exit, so that we can come back to the queue // after the lock has been released (otherwise we could get stuck here forever while (IsRunning && integrationQueue.HasItemPendingOnQueue(project) && !integrationQueue.IsBlocked) { Thread.Sleep(200); } } return(ran); }