public void RunNantAndExecTaskWithArgumentsOnSingleAndMultiLines() { const string ProjectName1 = "NantTest01"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "NantAndExecTestMultiLineBuildArgs.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>(); string workingDirectory = "Nant01"; var ios = new CCNet.Core.Util.IoService(); ios.DeleteIncludingReadOnlyObjects(workingDirectory); System.IO.Directory.CreateDirectory(workingDirectory); string NantBuildFile = @"IntegrationScenarios\Nant.Build"; var NantExeLocation = ""; #if DEBUG NantExeLocation = @"..\..\..\..\Tools\Nant\nant.exe"; #else NantExeLocation = @"..\..\Tools\Nant\nant.exe"; #endif var configFileData = System.IO.File.ReadAllText(CCNetConfigFile); configFileData = configFileData.Replace("WillBeReplacedViaTheTest", NantExeLocation); System.IO.File.WriteAllText(CCNetConfigFile, configFileData); System.IO.File.Copy(NantBuildFile, System.IO.Path.Combine(workingDirectory, new System.IO.FileInfo(NantBuildFile).Name)); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); CCNet.Remote.ProjectStatus ps = null; // checking data of project 1 foreach (var p in psr.Projects) { if (p.Name == ProjectName1) { ps = p; } } Assert.AreEqual(ProjectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + ProjectName1); }
public void ForceBuildOf1ProjectAndCheckBasicPropertiesOfProjectStatus() { const string ProjectName1 = "test01"; const string ProjectName2 = "test02"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "Simple.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; IntegrationCompleted.Add(ProjectName1, false); IntegrationCompleted.Add(ProjectName2, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); CCNet.Remote.Messages.ProjectRequest pr2 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName2); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(2, psr.Projects.Count, "Amount of projects in configfile is not correct." + CCNetConfigFile); CCNet.Remote.ProjectStatus ps = null; Log("checking data of project " + ProjectName1); foreach (var p in psr.Projects) { if (p.Name == ProjectName1) { ps = p; } } Assert.AreEqual(ProjectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus); Assert.IsTrue(ps.Activity.IsSleeping(), "Activity should be sleeping after an integration"); Assert.AreEqual(ps.Category, "cat1"); Assert.AreEqual(string.Empty, ps.CurrentMessage, "message should be empty after an ok build"); Assert.AreEqual("first testing project", ps.Description); Assert.AreEqual("1", ps.LastBuildLabel); Assert.AreEqual("1", ps.LastSuccessfulBuildLabel); Assert.AreEqual(0, ps.Messages.Length); Assert.AreEqual("Q1", ps.Queue); Assert.AreEqual(1, ps.QueuePriority); Assert.AreEqual(System.Environment.MachineName, ps.ServerName); Assert.AreEqual(CCNet.Remote.ProjectIntegratorState.Running, ps.Status); Assert.AreEqual("http://confluence.public.thoughtworks.org", ps.WebURL); Log("checking data of project " + ProjectName2); foreach (var p in psr.Projects) { if (p.Name == ProjectName2) { ps = p; } } Assert.IsFalse(IntegrationCompleted[ProjectName2], "integration not done, event may not be fired"); Assert.AreEqual(ProjectName2, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Unknown, ps.BuildStatus); Assert.IsTrue(ps.Activity.IsSleeping(), "Activity should be still sleeping"); Assert.AreEqual(ps.Category, "cat2"); Assert.AreEqual(string.Empty, ps.CurrentMessage, "message should still be empty"); Assert.AreEqual("second testing project", ps.Description); Assert.AreEqual("UNKNOWN", ps.LastBuildLabel); Assert.AreEqual("UNKNOWN", ps.LastSuccessfulBuildLabel); Assert.AreEqual(0, ps.Messages.Length); Assert.AreEqual("Q1", ps.Queue); Assert.AreEqual(2, ps.QueuePriority); Assert.AreEqual(System.Environment.MachineName, ps.ServerName); Assert.AreEqual(CCNet.Remote.ProjectIntegratorState.Unknown, ps.Status); Assert.AreEqual("http://" + System.Environment.MachineName + "/ccnet", ps.WebURL, "Default url not correct"); }
public void Simulate() { const string projectName1 = "Test01"; var integrationFolder = System.IO.Path.Combine("scenarioTests", projectName1); var ccNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "CCNetConfigWithPreProcessor.xml"); var project1StateFile = new System.IO.FileInfo(projectName1 + ".state").FullName; IntegrationCompleted.Clear(); IntegrationCompleted.Add(projectName1, false); Log("Clear existing state file, to simulate first run : " + project1StateFile); System.IO.File.Delete(project1StateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(integrationFolder)) { System.IO.Directory.Delete(integrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; var pr1 = new CCNet.Remote.Messages.ProjectRequest(null, projectName1); Log("Making CruiseServerFactory"); var csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + ccNetConfigFile); using (var cruiseServer = csf.Create(true, ccNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); Log("Forcing build on project " + projectName1 + " to test the innertrigger"); CheckResponse(cruiseServer.ForceBuild(pr1)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete of : " + projectName1); while (!IntegrationCompleted[projectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(1, psr.Projects.Count, "Amount of projects in configfile is not correct." + ccNetConfigFile); CCNet.Remote.ProjectStatus ps = null; // checking data of project 1 foreach (var p in psr.Projects) { if (p.Name == projectName1) { ps = p; } } Assert.AreEqual(projectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName1); }
public void StartServer_ForceBuildDependendProject_Wait_CheckingProjectDoesNotGetTriggered() { const string projectName1 = "InnerTriggerTest_CCNet1835"; const string projectName2 = "CheckBuild"; IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>(); string IntegrationFolder = System.IO.Path.Combine("scenarioTests", projectName1); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "ProblemWithInnerTriggers_CCnet1835.xml"); string Project1StateFile = new System.IO.FileInfo(projectName1 + ".state").FullName; string Project2StateFile = new System.IO.FileInfo(projectName2 + ".state").FullName; IntegrationCompleted.Add(projectName1, false); IntegrationCompleted.Add(projectName2, false); const Int32 SecondsToWaitFromNow = 60; // adjust triggertime of project 1 to now + 60 seconds (SecondsToWaitFromNow) // this will give the unittest time to create an ok build of project2 // and let the schedule trigger work as normal : check if it is time to integrate and check on the status // 60 seconds should be ok, less time may give problems on slower machines // keep in mind that cruise server is also starting, so this time must also be taken into account // also we want the cruise server to wait for 1 minute, otherwise it starts integrating project 1 immediately System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument(); xdoc.Load(CCNetConfigFile); string xslt = string.Format(System.Globalization.CultureInfo.CurrentCulture, "/cruisecontrol/project[@name='{0}']/triggers/multiTrigger/triggers/scheduleTrigger", projectName1); var scheduleTrigger = xdoc.SelectSingleNode(xslt); if (scheduleTrigger == null) { throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Schedule trigger not found via xslt {0} in configfile {1}", xslt, CCNetConfigFile)); } string newIntegrationTime = System.DateTime.Now.AddSeconds(SecondsToWaitFromNow).ToString("HH:mm"); Log("--------------------------------------------------------------------------"); Log(string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} is scheduled to integrate at {1}", projectName1, newIntegrationTime)); Log("--------------------------------------------------------------------------"); scheduleTrigger.Attributes["time"].Value = newIntegrationTime; xdoc.Save(CCNetConfigFile); Log("Clear existing state file, to simulate first run : " + Project1StateFile); System.IO.File.Delete(Project1StateFile); Log("Clear existing state file, to simulate first run : " + Project2StateFile); System.IO.File.Delete(Project2StateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, projectName1); CCNet.Remote.Messages.ProjectRequest pr2 = new CCNet.Remote.Messages.ProjectRequest(null, projectName2); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); Log("Forcing build on project " + projectName2 + " so it has a ok build state"); CheckResponse(cruiseServer.ForceBuild(pr2)); System.Threading.Thread.Sleep(250); // give time to start the build Log("Waiting for integration to complete of : " + projectName2); while (!IntegrationCompleted[projectName2]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } Log("Waiting for integration to complete of : " + projectName1); while (!IntegrationCompleted[projectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(CruiseServerIntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(2, psr.Projects.Count, "Amount of projects in configfile is not correct." + CCNetConfigFile); CCNet.Remote.ProjectStatus ps = null; // checking data of project 1 foreach (var p in psr.Projects) { if (p.Name == projectName1) { ps = p; } } Assert.AreEqual(projectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName1); // checking data of project 2 foreach (var p in psr.Projects) { if (p.Name == projectName2) { ps = p; } } Assert.AreEqual(projectName2, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus, "wrong build state for project " + projectName2); }
public void ForceBuildOfBadProjectAfterGoodWithDefaultLabelerWithInitialBuildLabelMustHaveInitialBuildLabelAsLastBuildLabel() { // in the labeller is a comparison with previous integration result, and an ITaskResult that always returns true for CheckIfSuccess // this looks weird and should be investigated // old part of the codebase since 2009 const string ProjectName1 = "LabelTest"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string WorkingFolder = System.IO.Path.Combine(IntegrationFolder, "wf"); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "Simple02.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; string CheckFileOfConditionalTask = System.IO.Path.Combine(WorkingFolder, "checkFile.txt"); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.IO.File.WriteAllText(CheckFileOfConditionalTask, "hello"); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build - conditional ok"); CheckResponse(cruiseServer.ForceBuild(pr1)); Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } IntegrationCompleted[ProjectName1] = false; System.IO.File.Delete(CheckFileOfConditionalTask); System.Threading.Thread.Sleep(250); // give time to finish delete Log("Forcing build - conditional Not ok"); CheckResponse(cruiseServer.ForceBuild(pr1)); Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(1, psr.Projects.Count, "Amount of projects in configfile is not correct." + CCNetConfigFile); CCNet.Remote.ProjectStatus ps = null; Log("checking data of project " + ProjectName1); foreach (var p in psr.Projects) { if (p.Name == ProjectName1) { ps = p; } } // 1 good build and 1 bad Assert.AreEqual(ProjectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Failure, ps.BuildStatus); Assert.AreEqual("bad task", ps.CurrentMessage, "message should be the descripton / name of the failing task"); Assert.AreEqual("1.5.1603", ps.LastBuildLabel, "do not increase label, because the increase on failure is set to false"); Assert.AreEqual("1.5.1603", ps.LastSuccessfulBuildLabel, "do not increase label, because the increase on failure is set to false"); }
public void ForceBuildOfGoodProjectWithDefaultLabelerWithInitialBuildLabelMustHaveInitialBuildLabelAsLastBuildLabel() { const string ProjectName1 = "LabelTest"; string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1); string WorkingFolder = System.IO.Path.Combine(IntegrationFolder, "wf"); string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "Simple02.xml"); string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName; string CheckFileOfConditionalTask = System.IO.Path.Combine(WorkingFolder, "checkFile.txt"); IntegrationCompleted.Add(ProjectName1, false); Log("Clear existing state file, to simulate first run : " + ProjectStateFile); System.IO.File.Delete(ProjectStateFile); Log("Clear integration folder to simulate first run"); if (System.IO.Directory.Exists(IntegrationFolder)) { System.IO.Directory.Delete(IntegrationFolder, true); } CCNet.Remote.Messages.ProjectStatusResponse psr; CCNet.Remote.Messages.ProjectRequest pr1 = new CCNet.Remote.Messages.ProjectRequest(null, ProjectName1); Log("Making CruiseServerFactory"); CCNet.Core.CruiseServerFactory csf = new CCNet.Core.CruiseServerFactory(); Log("Making cruiseServer with config from :" + CCNetConfigFile); using (var cruiseServer = csf.Create(true, CCNetConfigFile)) { // subscribe to integration complete to be able to wait for completion of a build cruiseServer.IntegrationCompleted += new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("Starting cruiseServer"); cruiseServer.Start(); System.IO.File.WriteAllText(CheckFileOfConditionalTask, "hello"); System.Threading.Thread.Sleep(250); // give time to start Log("Forcing build - conditional ok"); CheckResponse(cruiseServer.ForceBuild(pr1)); Log("Waiting for integration to complete"); while (!IntegrationCompleted[ProjectName1]) { for (int i = 1; i <= 4; i++) { System.Threading.Thread.Sleep(250); } Log(" waiting ..."); } // un-subscribe to integration complete cruiseServer.IntegrationCompleted -= new EventHandler <ThoughtWorks.CruiseControl.Remote.Events.IntegrationCompletedEventArgs>(cruiseServer_IntegrationCompleted); Log("getting project status"); psr = cruiseServer.GetProjectStatus(pr1); CheckResponse(psr); Log("Stopping cruiseServer"); cruiseServer.Stop(); Log("waiting for cruiseServer to stop"); cruiseServer.WaitForExit(pr1); Log("cruiseServer stopped"); } Log("Checking the data"); Assert.AreEqual(1, psr.Projects.Count, "Amount of projects in configfile is not correct." + CCNetConfigFile); CCNet.Remote.ProjectStatus ps = null; Log("checking data of project " + ProjectName1); foreach (var p in psr.Projects) { if (p.Name == ProjectName1) { ps = p; } } // 1 good build Assert.AreEqual(ProjectName1, ps.Name); Assert.AreEqual(CCNet.Remote.IntegrationStatus.Success, ps.BuildStatus); Assert.AreEqual(string.Empty, ps.CurrentMessage, "message should be empty after ok build"); Assert.AreEqual("1.5.1603", ps.LastBuildLabel, "after ok build with initial label, the result must be the inital label"); Assert.AreEqual("1.5.1603", ps.LastSuccessfulBuildLabel, "after ok build with initial label, the result must be the inital label"); Assert.AreEqual(0, ps.Messages.Length); }