Exemple #1
0
        public void PackagePublisherPackageFolderMustRespectHierarchy()
        {
            const string ProjectName1 = "PackageTest03";

            string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1);
            string CCNetConfigFile   = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest03.xml");
            string ProjectStateFile  = new System.IO.FileInfo(ProjectName1 + ".state").FullName;

            IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>();

            string workingDirectory = "Packaging03";

            string infoFolder    = string.Format("{0}{1}some{1}directories{1}deeper{1}_PublishedWebsites{1}MyProject{1}", workingDirectory, System.IO.Path.DirectorySeparatorChar);
            string subInfoFolder = string.Format("{0}{1}AFolder{1}", infoFolder, System.IO.Path.DirectorySeparatorChar);
            string f1            = string.Format("{0}{1}a.txt", infoFolder, System.IO.Path.DirectorySeparatorChar);
            string f2            = string.Format("{0}{1}b.txt", subInfoFolder, System.IO.Path.DirectorySeparatorChar);


            var ios = new CCNet.Core.Util.IoService();

            ios.DeleteIncludingReadOnlyObjects(infoFolder);
            ios.DeleteIncludingReadOnlyObjects("TheMegaWebSite");


            System.IO.Directory.CreateDirectory(infoFolder);
            System.IO.Directory.CreateDirectory(subInfoFolder);


            System.IO.File.WriteAllText(f1, "somedata");
            System.IO.File.WriteAllText(f2, "somedata");

            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");
            string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}Project-package.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar);

            Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location");

            ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile);
            string expectedFiles = string.Empty;

            foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf)
            {
                System.Diagnostics.Debug.WriteLine(ze.Name);
                expectedFiles += ze.Name;
            }

            Assert.AreEqual(@"MegaWebSite/AFolder/b.txtMegaWebSite/a.txt", expectedFiles);
        }
Exemple #2
0
        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 PackagePublisherWithoutFlattenFiles()
        {
            const string ProjectName1 = "PackageTest02";

            string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1);
            string CCNetConfigFile   = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest02" + (Platform.IsWindows ? "" : "_linux") + ".xml");
            string ProjectStateFile  = new System.IO.FileInfo(ProjectName1 + ".state").FullName;

            IntegrationCompleted = new System.Collections.Generic.Dictionary <string, bool>();

            string workingDirectory = "Packaging02";
            string InfoFolder       = "Info";
            string subInfoFolder    = "Sub1";

            string FolderContainingFiles = string.Format("{0}{3}{1}{3}{2}", workingDirectory, InfoFolder, subInfoFolder, System.IO.Path.DirectorySeparatorChar);
            string f1 = string.Format("{0}{1}a.txt", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar);
            string f2 = string.Format("{0}{1}b.txt", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar);
            string f3 = string.Format("{0}{1}c.rtf", FolderContainingFiles, System.IO.Path.DirectorySeparatorChar);


            var ios = new CCNet.Core.Util.IoService();

            ios.DeleteIncludingReadOnlyObjects(FolderContainingFiles);

            System.IO.Directory.CreateDirectory(FolderContainingFiles);
            System.IO.File.WriteAllText(f1, "somedata");
            System.IO.File.WriteAllText(f2, "somedata");

            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");
            string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}TestPackage.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar);

            Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location");

            ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile);
            List <string> actualFiles = new List <string>();

            foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf)
            {
                System.Diagnostics.Debug.WriteLine(ze.Name);
                actualFiles.Add(ze.Name);
            }
            actualFiles.Sort();

            Assert.AreEqual(@"Info/Sub1/a.txtInfo/Sub1/b.txt", String.Join("", actualFiles));
        }
        public void PackagePublisherPackageFolderMustRespectHierarchy()
        {
            const string ProjectName1 = "PackageTest03";

            string IntegrationFolder = System.IO.Path.Combine("scenarioTests", ProjectName1);
            string CCNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "PackagePublisherTest03.xml");
            string ProjectStateFile = new System.IO.FileInfo(ProjectName1 + ".state").FullName;

            IntegrationCompleted = new System.Collections.Generic.Dictionary<string, bool>();

            string workingDirectory = "Packaging03";

            string infoFolder = string.Format("{0}{1}some{1}directories{1}deeper{1}_PublishedWebsites{1}MyProject{1}", workingDirectory, System.IO.Path.DirectorySeparatorChar);
            string subInfoFolder = string.Format("{0}{1}AFolder{1}", infoFolder, System.IO.Path.DirectorySeparatorChar);
            string f1 = string.Format("{0}{1}a.txt", infoFolder, System.IO.Path.DirectorySeparatorChar);
            string f2 = string.Format("{0}{1}b.txt", subInfoFolder, System.IO.Path.DirectorySeparatorChar);


            var ios = new CCNet.Core.Util.IoService();
            ios.DeleteIncludingReadOnlyObjects(infoFolder);
            ios.DeleteIncludingReadOnlyObjects("TheMegaWebSite");


            System.IO.Directory.CreateDirectory(infoFolder);
            System.IO.Directory.CreateDirectory(subInfoFolder);


            System.IO.File.WriteAllText(f1, "somedata");
            System.IO.File.WriteAllText(f2, "somedata");

            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");
            string ExpectedZipFile = string.Format("{0}{1}Artifacts{1}1{1}Project-package.zip", ProjectName1, System.IO.Path.DirectorySeparatorChar);
            Assert.IsTrue(System.IO.File.Exists(ExpectedZipFile), "zip package not found at expected location");

            ICSharpCode.SharpZipLib.Zip.ZipFile zf = new ICSharpCode.SharpZipLib.Zip.ZipFile(ExpectedZipFile);
            string expectedFiles = string.Empty;

            foreach (ICSharpCode.SharpZipLib.Zip.ZipEntry ze in zf)
            {
                System.Diagnostics.Debug.WriteLine(ze.Name);
                expectedFiles += ze.Name;
            }

            Assert.AreEqual(@"MegaWebSite/AFolder/b.txtMegaWebSite/a.txt", expectedFiles);
        }
        public void Simulate()
        {
            const string projectName1 = "triggerTest01";
            const string projectName2 = "triggerTest02";


            var integrationFolder = System.IO.Path.Combine("scenarioTests", projectName1);
            var ccNetConfigFile = System.IO.Path.Combine("IntegrationScenarios", "Triggers.xml");
            var project1StateFile = new System.IO.FileInfo(projectName1 + ".state").FullName;
            var project2StateFile = new System.IO.FileInfo(projectName2 + ".state").FullName;

            IntegrationCompleted.Add(projectName1, false);
            IntegrationCompleted.Add(projectName2, false);

            const Int32 secondsToWaitFromNow = 120;
            // adjust triggertime of project 1 to now + 70 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
            // 70 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 cuise server to wait for 1 minute, otherwise it starts integrating project 1 immediately
            var xdoc = new System.Xml.XmlDocument();
            xdoc.Load(ccNetConfigFile);
            var xslt = string.Format(System.Globalization.CultureInfo.CurrentCulture,"/cruisecontrol/project[@name='{0}']/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));
            }

            var 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;
            var pr1 = new CCNet.Remote.Messages.ProjectRequest(null, projectName1);
            var pr2 = new CCNet.Remote.Messages.ProjectRequest(null, projectName2);



            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(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.Unknown , ps.BuildStatus, "wrong build state for project " + projectName2);


        }
        /// <summary>
        /// Starts the actual application.
        /// </summary>
        /// <param name="args">The arguments for the application.</param>
        /// <param name="usesShadowCopying">A flag indicating whether shadow copying should be used.</param>
        /// <returns>
        /// The return code for the application.
        /// </returns>
        public int Run(string[] args, bool usesShadowCopying)
        {
            // Parse the command line arguments
            var webOptions = new WebApiOptions();
            var consoleArgs = new ConsoleRunnerArguments();
            var opts = new OptionSet();
            opts.Add("h|?|help", "display this help screen", v => consoleArgs.ShowHelp = v != null)
                .Add("c|config=", "the configuration file to use (defaults to ccnet.conf)", v => consoleArgs.ConfigFile = v)
                .Add("r|remoting=", "turn remoting on/off (defaults to on)", v => consoleArgs.UseRemoting = v == "on")
                .Add("p|project=", "the project to integrate (???)", v => consoleArgs.Project = v)
                .Add("v|validate", "validate the configuration file and exit", v => consoleArgs.ValidateConfigOnly = v != null)
                .Add("l|logging=", "turn logging on/off (defaults to on)", v => consoleArgs.Logging = v == "on")
                .Add("sc|shadowCopy=", "turn shadow copying on/off (defaults to on)", v => usesShadowCopying = v == "on")
                .Add("e|errorpause=", "turn pause on error on/off (defaults to on)", v => consoleArgs.PauseOnError = v == "on")
                .Add("we|webEndPoint=", "the base endpoint for the web API (default none)", v => webOptions.BaseEndpoint = v);
            try
            {
                opts.Parse(args);
            }
            catch (OptionException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                return 1;
            }

            // Display the help
            if (consoleArgs.ShowHelp)
            {
                DisplayHelp(opts);
                return 0;
            }

            ICruiseServerFactory factory = null;
            try
            {
                // Start the actual console runner
                if (webOptions.IsConfigured)
                {
                    var apiFactory = new WebApiServerFactory();
                    apiFactory.StartWebApi(apiFactory, webOptions);
                    factory = apiFactory;
                }
                else
                {
                    factory = new CruiseServerFactory();
                }

                runner = new ConsoleRunner(consoleArgs, factory);
                if (!usesShadowCopying)
                {
                    Log.Warning("Shadow-copying has been turned off - hot-swapping will not work!");
                }

                runner.Run();
                return 0;
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                if (consoleArgs.PauseOnError)
                {
                    Console.WriteLine("An unexpected error has caused the console to crash");
                    Console.ReadKey();
                }
                return 2;
            }
            finally
            {
                // Clean up 
                runner = null;
                var disposable = factory as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }