diff --git a/project/CCCmd/CommandType.cs b/project/CCCmd/CommandType.cs index c51308189..795f34fd0 100644 --- a/project/CCCmd/CommandType.cs +++ b/project/CCCmd/CommandType.cs @@ -1,12 +1,15 @@ -namespace ThoughtWorks.CruiseControl.CCCmd +namespace ThoughtWorks.CruiseControl.CCCmd { public enum CommandType { Retrieve, ForceBuild, + CancelPending, AbortBuild, StartProject, StopProject, + Volunteer, + CancelVolunteer, Help } } diff --git a/project/CCCmd/Help.txt b/project/CCCmd/Help.txt index 5b96e5aa4..8cd1a9021 100644 --- a/project/CCCmd/Help.txt +++ b/project/CCCmd/Help.txt @@ -1,4 +1,4 @@ -CruiseControl.Net Command-Line Utility +CruiseControl.Net Command-Line Utility Provides command-line access to a CruiseControl.Net server CCCmd [options] @@ -7,8 +7,11 @@ command: one of the following actions help: display this help screen retrieve: retrieve details on a project or server forcebuild: forces a build on a project + cancelpending: remove a build from the queue abortbuild: aborts a build on a project startproject: starts a project integrator stopproject: stops a project integrator + volunteer: sets you as the fixer + cancelvolunteer: remove the fixer from a project options: diff --git a/project/CCCmd/Program.cs b/project/CCCmd/Program.cs index 4f96ec303..a8583e5d4 100644 --- a/project/CCCmd/Program.cs +++ b/project/CCCmd/Program.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Reflection; @@ -13,7 +13,7 @@ namespace ThoughtWorks.CruiseControl.CCCmd { class Program { - private static bool help; + private static bool help; private static string server; private static string target; private static string project; @@ -26,11 +26,12 @@ class Program private static string userName; private static string password; private static bool xml; + private static string volunteer_name = Environment.UserName; private static BuildCondition condition = BuildCondition.ForceBuild; static void Main(string[] args) { - OptionSet opts = new OptionSet(); + OptionSet opts = new OptionSet(); opts.Add("h|?|help", "display this help screen", delegate(string v) { help = v != null; }) .Add("s|server=", "the CruiseControl.Net server to send the commands to (required for all actions except help)", delegate(string v) { server = v; }) .Add("t|target=", "the target server for all messages", delegate(string v) { target = v; }) @@ -39,33 +40,34 @@ static void Main(string[] args) .Add("q|quiet", "run in quiet mode (do not print messages)", delegate(string v) { quiet = v != null; }) .Add("ime|ifmodificationexists", "only force the build if modification exist", delegate(string v) { condition = v != null ? BuildCondition.IfModificationExists : BuildCondition.ForceBuild; }) .Add("r|params=", "a semicolon separated list of name value pairs", delegate(string v) { string_params = v; }) - .Add("f|params_file=", "the name of a XML file containing the parameters values to use when forcing a build. If specified at the same time as this flag, the values from the command line are ignored", delegate(string v) { params_filename = v; }) - .Add("x|xml", "outputs the details in XML format instead of plain text (only valid for retrieve)", delegate(string v) { xml = v != null; }) + .Add("f|params_file=", "the name of a XML file containing the parameters values to use when forcing a build. If specified at the same time as this flag, the values from the command line are ignored", delegate(string v) { params_filename = v; }) + .Add("x|xml", "outputs the details in XML format instead of plain text (only valid for retrieve)", delegate(string v) { xml = v != null; }) .Add("user=", "the user of the user account to use", v => { userName = v; }) - .Add("pwd=", "the password to use for the user", v => { password = v;}); - try - { - extra = opts.Parse(args); - } - catch (OptionException e) - { - Console.WriteLine(e.Message); - Console.WriteLine(e.StackTrace); - return; - } - - if((extra.Count == 1) && !help) - { - command = (CommandType) Enum.Parse(typeof(CommandType), extra[0], true); - } - else - { - DisplayHelp(opts); - return; - } - + .Add("pwd=", "the password to use for the user", v => { password = v; }) + .Add("volunteer_name=", "the name to use when volunteering (defaults to Environment.UserName)", v => { volunteer_name = v; }); try - { + { + extra = opts.Parse(args); + } + catch (OptionException e) + { + Console.WriteLine(e.Message); + Console.WriteLine(e.StackTrace); + return; + } + + if ((extra.Count == 1) && !help) + { + command = (CommandType)Enum.Parse(typeof(CommandType), extra[0], true); + } + else + { + DisplayHelp(opts); + return; + } + + try + { switch (command) { case CommandType.Help: @@ -77,6 +79,9 @@ static void Main(string[] args) case CommandType.ForceBuild: RunForceBuild(); break; + case CommandType.CancelPending: + RunCancelPending(); + break; case CommandType.AbortBuild: RunAbortBuild(); break; @@ -86,6 +91,12 @@ static void Main(string[] args) case CommandType.StopProject: RunStopProject(); break; + case CommandType.Volunteer: + RunVolunteer(); + break; + case CommandType.CancelVolunteer: + RunCancelVolunteer(); + break; default: throw new CruiseControlException("Unknown action: " + command.ToString()); } @@ -110,7 +121,7 @@ private static CruiseServerClientBase GenerateClient() private static void RunForceBuild() { if (ValidateParameter(server, "--server") && - ValidateNotAll() && + ValidateNotAll() && ValidateParameter(project, "--project")) { try @@ -134,7 +145,7 @@ private static void RunForceBuild() string[] splittedNameValuePair = nameValuePair.Split('='); userParameters.Add(splittedNameValuePair[0], splittedNameValuePair[1]); } - } + } using (var client = GenerateClient()) @@ -144,21 +155,21 @@ private static void RunForceBuild() foreach (ParameterBase parameter in parameters) { - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Parameter: {0}", parameter.Name), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Parameter: {0}", parameter.Name), ConsoleColor.Gray); bool required = false; PropertyInfo propInfos = parameter.GetType().GetProperty("IsRequired"); if (propInfos == null) - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"propInfos is null, considering that parameter {0} is not required", parameter.Name), ConsoleColor.DarkYellow); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "propInfos is null, considering that parameter {0} is not required", parameter.Name), ConsoleColor.DarkYellow); else required = (bool)propInfos.GetValue(parameter, null); - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Kind: {0}", parameter.ToString()), ConsoleColor.Gray); - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Data type: {0}", parameter.DataType), ConsoleColor.Gray); - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Required: {0}", required), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Kind: {0}", parameter.ToString()), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Data type: {0}", parameter.DataType), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Required: {0}", required), ConsoleColor.Gray); string userProvidedValue; userParameters.TryGetValue(parameter.Name, out userProvidedValue); - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," User provided value: {0}", userProvidedValue), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " User provided value: {0}", userProvidedValue), ConsoleColor.Gray); var convertedValue = parameter.Convert(userProvidedValue); string convertedValueString = userProvidedValue; @@ -166,16 +177,16 @@ private static void RunForceBuild() { convertedValueString = convertedValue.ToString(); } - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Converted value: {0}", convertedValueString), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Converted value: {0}", convertedValueString), ConsoleColor.Gray); - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Default value: {0}", parameter.DefaultValue), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Default value: {0}", parameter.DefaultValue), ConsoleColor.Gray); if (parameter.AllowedValues == null) { if (!quiet) WriteLine(" Allowed values: null", ConsoleColor.Gray); } else { - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture," Allowed values: {0}", parameter.AllowedValues), ConsoleColor.Gray); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, " Allowed values: {0}", parameter.AllowedValues), ConsoleColor.Gray); bool isAllowedValue = false; int i = 0; @@ -186,16 +197,16 @@ private static void RunForceBuild() } if (!isAllowedValue) - throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Parameter {0} was given value {1} which is not one of the allowed ones ({2})", parameter.Name, userProvidedValue, string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0}", parameter.AllowedValues))); + throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Parameter {0} was given value {1} which is not one of the allowed ones ({2})", parameter.Name, userProvidedValue, string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}", parameter.AllowedValues))); } if (required && String.IsNullOrEmpty(convertedValueString) && String.IsNullOrEmpty(parameter.DefaultValue)) - throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Parameter {0} is required but was not provided and does not have a default value", parameter.Name)); + throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Parameter {0} is required but was not provided and does not have a default value", parameter.Name)); buildParameters.Add(new NameValuePair(parameter.Name, convertedValueString)); - } + } - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Sending ForceBuild request for '{0}'", project), ConsoleColor.White); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Sending ForceBuild request for '{0}'", project), ConsoleColor.White); client.ForceBuild(project, buildParameters, condition); if (!quiet) WriteLine("ForceBuild request sent", ConsoleColor.White); } @@ -207,6 +218,29 @@ private static void RunForceBuild() } } + private static void RunCancelPending() + { + if (ValidateParameter(server, "--server") && + ValidateNotAll() && + ValidateParameter(project, "--project")) + { + try + { + using (var client = GenerateClient()) + { + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Sending CancelPending request for '{0}'", project), + ConsoleColor.White); + client.CancelPendingRequest(project); + if (!quiet) WriteLine("CancelPending request sent", ConsoleColor.White); + } + } + catch (Exception error) + { + WriteError("ERROR: Unable to send CancelPending request", error); + } + } + } + private static void RunAbortBuild() { if (ValidateParameter(server, "--server") && @@ -217,7 +251,7 @@ private static void RunAbortBuild() { using (var client = GenerateClient()) { - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Sending AbortBuild request for '{0}'", project), ConsoleColor.White); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Sending AbortBuild request for '{0}'", project), ConsoleColor.White); client.AbortBuild(project); if (!quiet) WriteLine("AbortBuild request sent", ConsoleColor.White); } @@ -239,7 +273,7 @@ private static void RunStartProject() { using (var client = GenerateClient()) { - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Sending StartProject request for '{0}'", project), ConsoleColor.White); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Sending StartProject request for '{0}'", project), ConsoleColor.White); client.StartProject(project); if (!quiet) WriteLine("StartProject request sent", ConsoleColor.White); } @@ -261,7 +295,7 @@ private static void RunStopProject() { using (var client = GenerateClient()) { - if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Sending StopProject request for '{0}'", project), ConsoleColor.White); + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Sending StopProject request for '{0}'", project), ConsoleColor.White); client.StopProject(project); if (!quiet) WriteLine("StopProject request sent", ConsoleColor.White); } @@ -273,11 +307,57 @@ private static void RunStopProject() } } + private static void RunVolunteer() + { + if (ValidateParameter(server, "--server") && + ValidateNotAll() && + ValidateParameter(project, "--project")) + { + try + { + using (var client = GenerateClient()) + { + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Volunteering to fix '{0}'", project), ConsoleColor.White); + string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0} is fixing the build.", volunteer_name); + client.SendMessage(project, new Message(message, Message.MessageKind.Fixer)); + if (!quiet) WriteLine("Volunteer message sent", ConsoleColor.White); + } + } + catch (Exception error) + { + WriteError("ERROR: Unable to volunteer", error); + } + } + } + + private static void RunCancelVolunteer() + { + if (ValidateParameter(server, "--server") && + ValidateNotAll() && + ValidateParameter(project, "--project")) + { + try + { + using (var client = GenerateClient()) + { + if (!quiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Removing the fixer in '{0}'", project), + ConsoleColor.White); + client.SendMessage(project, new Message(string.Empty, Message.MessageKind.Fixer)); + if (!quiet) WriteLine("CancelVolunteer message sent", ConsoleColor.White); + } + } + catch (Exception error) + { + WriteError("ERROR: Unable to volunteer", error); + } + } + } + private static void RunRetrive() { if (ValidateParameter(server, "--server")) { - if (string.IsNullOrEmpty(project) && !all) + if (string.IsNullOrEmpty(project) && !all) { WriteLine("Must specify either a project or use the '-all' option", ConsoleColor.Red); } @@ -317,7 +397,7 @@ private static void DisplayServerStatus(CruiseServerClientBase client, bool isQu { DisplayProject(prj); } - } + } } catch (Exception error) { @@ -329,7 +409,7 @@ private static void DisplayProjectStatus(CruiseServerClientBase client, string p { try { - if (!isQuiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Retrieving project '{0}' on server {1}", projectName, client.TargetServer), ConsoleColor.Gray); + if (!isQuiet) WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Retrieving project '{0}' on server {1}", projectName, client.TargetServer), ConsoleColor.Gray); CruiseServerSnapshot snapShot = client.GetCruiseServerSnapshot(); var wasFound = false; foreach (ProjectStatus project in snapShot.ProjectStatuses) @@ -346,8 +426,8 @@ private static void DisplayProjectStatus(CruiseServerClientBase client, string p else { DisplayProject(project); - } - + } + wasFound = true; break; } @@ -366,9 +446,9 @@ private static void DisplayProjectStatus(CruiseServerClientBase client, string p private static void DisplayProject(ProjectStatus project) { - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0}: {1}", project.Name, project.Status), ConsoleColor.White); - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tActivity: {0}", project.Activity), ConsoleColor.White); - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tBuild Status: {0}", project.BuildStatus), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0}: {1}", project.Name, project.Status), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tActivity: {0}", project.Activity), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tBuild Status: {0}", project.BuildStatus), ConsoleColor.White); if (!string.IsNullOrEmpty(project.BuildStage)) { XmlDocument stageXml = new XmlDocument(); @@ -379,23 +459,23 @@ private static void DisplayProject(ProjectStatus project) { string stageTime = stageItem.GetAttribute("Time"); string stageData = stageItem.GetAttribute("Data"); - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tBuild Stage: {0} ({1})", stageData, stageTime), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tBuild Stage: {0} ({1})", stageData, stageTime), ConsoleColor.White); } } catch { - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tBuild Stage: {0}", project.BuildStage), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tBuild Stage: {0}", project.BuildStage), ConsoleColor.White); } } - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tLast Build: {0:G}", project.LastBuildDate), ConsoleColor.White); - WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture,"\tNext Build: {0:G}", project.NextBuildTime), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tLast Build: {0:G}", project.LastBuildDate), ConsoleColor.White); + WriteLine(string.Format(System.Globalization.CultureInfo.CurrentCulture, "\tNext Build: {0:G}", project.NextBuildTime), ConsoleColor.White); } private static bool ValidateParameter(string value, string name) { if (string.IsNullOrEmpty(value)) { - WriteError(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Input parameter '{0}' is missing", name), null); + WriteError(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Input parameter '{0}' is missing", name), null); return false; } return true; @@ -405,7 +485,7 @@ private static bool ValidateNotAll() { if (all) { - WriteError(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Input parameter '--all' is not valid for {0}", command), null); + WriteError(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Input parameter '--all' is not valid for {0}", command), null); return false; } return true; @@ -459,13 +539,13 @@ private static void DisplayHelp(OptionSet opts) { helpStream.Close(); } - opts.WriteOptionDescriptions (Console.Out); + opts.WriteOptionDescriptions(Console.Out); Console.WriteLine(); WriteLine("Layout of the parameter file :", ConsoleColor.Yellow); - WriteLine(xmlParamFileLayout,ConsoleColor.DarkGray); + WriteLine(xmlParamFileLayout, ConsoleColor.DarkGray); Console.WriteLine(); - WriteLine(" Examples :",ConsoleColor.Yellow); + WriteLine(" Examples :", ConsoleColor.Yellow); WriteLine("-==========-", ConsoleColor.Yellow); WriteLine(" CCCmd.exe retrieve -s=tcp://localhost:21234/CruiseManager.rem -a", ConsoleColor.White); WriteLine(" CCCmd.exe retrieve -s=tcp://localhost:21234/CruiseManager.rem -a -x", ConsoleColor.White); @@ -474,7 +554,7 @@ private static void DisplayHelp(OptionSet opts) WriteLine(" CCCmd.exe forcebuild -s=tcp://localhost:21234/CruiseManager.rem -p=ccnet -r=buildtype=fulltest", ConsoleColor.White); WriteLine(" CCCmd.exe forcebuild -s=tcp://localhost:21234/CruiseManager.rem -p=ccnet -r=buildtype=fulltest;makepackage=true", ConsoleColor.White); - + } diff --git a/project/CCTrayLib/Monitoring/RemotingCruiseProjectManager.cs b/project/CCTrayLib/Monitoring/RemotingCruiseProjectManager.cs index 07de7d5b5..6d5613456 100644 --- a/project/CCTrayLib/Monitoring/RemotingCruiseProjectManager.cs +++ b/project/CCTrayLib/Monitoring/RemotingCruiseProjectManager.cs @@ -6,24 +6,24 @@ namespace ThoughtWorks.CruiseControl.CCTrayLib.Monitoring { - /// - /// Allows access to the state of a single cruise control project, over remoting - /// - public class RemotingCruiseProjectManager : ICruiseProjectManager - { + /// + /// Allows access to the state of a single cruise control project, over remoting + /// + public class RemotingCruiseProjectManager : ICruiseProjectManager + { private readonly CruiseServerClientBase manager; - private readonly string projectName; + private readonly string projectName; public RemotingCruiseProjectManager(CruiseServerClientBase manager, string projectName) - { - this.manager = manager; - this.projectName = projectName; - } + { + this.manager = manager; + this.projectName = projectName; + } public void ForceBuild(string sessionToken, Dictionary parameters, string userName) - { - try - { + { + try + { manager.DisplayName = userName; manager.SessionToken = sessionToken; if (parameters != null) @@ -35,112 +35,112 @@ public void ForceBuild(string sessionToken, Dictionary parameter { manager.ForceBuild(projectName); } - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } - public void FixBuild(string sessionToken, string fixingUserName) - { - string Fixer; - if (fixingUserName.Trim().Length == 0) - { - Fixer = Environment.UserName; - } - else - { - Fixer = fixingUserName; - } + public void FixBuild(string sessionToken, string fixingUserName) + { + string Fixer; + if (fixingUserName.Trim().Length == 0) + { + Fixer = Environment.UserName; + } + else + { + Fixer = fixingUserName; + } - try - { - string message = string.Format(System.Globalization.CultureInfo.CurrentCulture,"{0} is fixing the build.", Fixer); + try + { + string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, "Fixer: {0}.", Fixer); manager.SessionToken = sessionToken; manager.SendMessage(projectName, new Message(message, Message.MessageKind.Fixer)); - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } public void AbortBuild(string sessionToken, string userName) - { - try - { + { + try + { manager.DisplayName = userName; manager.SessionToken = sessionToken; manager.AbortBuild(projectName); - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } - + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } + public void StopProject(string sessionToken) - { - try - { + { + try + { manager.SessionToken = sessionToken; manager.StopProject(projectName); - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } - + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } + public void StartProject(string sessionToken) - { - try - { + { + try + { manager.SessionToken = sessionToken; manager.StartProject(projectName); - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } - + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } + public void CancelPendingRequest(string sessionToken) - { - try - { + { + try + { manager.SessionToken = sessionToken; manager.CancelPendingRequest(projectName); - } - // Silently ignore exceptions that occur due to connection problems - catch (System.Net.Sockets.SocketException) - { - } - catch (System.Runtime.Remoting.RemotingException) - { - } - } + } + // Silently ignore exceptions that occur due to connection problems + catch (System.Net.Sockets.SocketException) + { + } + catch (System.Runtime.Remoting.RemotingException) + { + } + } - public string ProjectName - { - get { return projectName; } - } + public string ProjectName + { + get { return projectName; } + } #region RetrieveSnapshot() /// @@ -187,5 +187,5 @@ public virtual List ListBuildParameters() { return manager.ListBuildParameters(projectName); } - } + } } diff --git a/project/CommonAssemblyInfo.cs b/project/CommonAssemblyInfo.cs index f4f9e9e8f..a6e346398 100644 --- a/project/CommonAssemblyInfo.cs +++ b/project/CommonAssemblyInfo.cs @@ -3,7 +3,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.18408 +// Runtime Version:4.0.30319.34014 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -12,7 +12,7 @@ [assembly: AssemblyCompanyAttribute("ThoughtWorks Inc.")] [assembly: AssemblyProductAttribute("CruiseControl.NET")] -[assembly: AssemblyCopyrightAttribute("Copyright © 2003 - 2014 ThoughtWorks Inc.")] +[assembly: AssemblyCopyrightAttribute("Copyright © 2003 - 2016 ThoughtWorks Inc.")] [assembly: AssemblyTrademarkAttribute("")] [assembly: AssemblyVersionAttribute("0.0.0.0")] [assembly: AssemblyFileVersionAttribute("0.0.0.0")] diff --git a/project/Remote/Message.cs b/project/Remote/Message.cs index e2ffbce26..d87230370 100644 --- a/project/Remote/Message.cs +++ b/project/Remote/Message.cs @@ -45,7 +45,12 @@ public enum MessageKind /// /// /// - BuildAbortedBy = 5 + BuildAbortedBy = 5, + /// + /// + /// + /// + ForceBuildPublisherFailed = 6 } private string message; @@ -137,4 +142,4 @@ public override int GetHashCode() return this.ToString().GetHashCode(); } } -} \ No newline at end of file +} diff --git a/project/UnitTests/WebDashboard/Dashboard/ProjectGridTest.cs b/project/UnitTests/WebDashboard/Dashboard/ProjectGridTest.cs index 50cecf6a0..7eb9fcd21 100644 --- a/project/UnitTests/WebDashboard/Dashboard/ProjectGridTest.cs +++ b/project/UnitTests/WebDashboard/Dashboard/ProjectGridTest.cs @@ -16,653 +16,653 @@ namespace ThoughtWorks.CruiseControl.UnitTests.WebDashboard.Dashboard { - [TestFixture] - public class ProjectGridTest - { + [TestFixture] + public class ProjectGridTest + { private MockRepository mocks = new MockRepository(); - private ProjectGrid projectGrid; - private ICruiseUrlBuilder urlBuilderMock; - private DynamicMock linkFactoryMock; - private IAbsoluteLink projectLink; - private IServerSpecifier serverSpecifier; - private IProjectSpecifier projectSpecifier; - - [SetUp] - public void Setup() - { + private ProjectGrid projectGrid; + private ICruiseUrlBuilder urlBuilderMock; + private DynamicMock linkFactoryMock; + private IAbsoluteLink projectLink; + private IServerSpecifier serverSpecifier; + private IProjectSpecifier projectSpecifier; + + [SetUp] + public void Setup() + { urlBuilderMock = mocks.DynamicMock(); SetupResult.For(urlBuilderMock.BuildProjectUrl(null, null)) .IgnoreArguments() .Return("myLinkUrl"); - linkFactoryMock = new DynamicMock(typeof(ILinkFactory)); - projectGrid = new ProjectGrid(); + linkFactoryMock = new DynamicMock(typeof(ILinkFactory)); + projectGrid = new ProjectGrid(); - serverSpecifier = new DefaultServerSpecifier("server"); - projectSpecifier = new DefaultProjectSpecifier(serverSpecifier, "my project"); + serverSpecifier = new DefaultServerSpecifier("server"); + projectSpecifier = new DefaultProjectSpecifier(serverSpecifier, "my project"); - projectLink = new GeneralAbsoluteLink("myLinkText", "myLinkUrl"); - } + projectLink = new GeneralAbsoluteLink("myLinkText", "myLinkUrl"); + } - private void VerifyAll() - { - linkFactoryMock.Verify(); - } + private void VerifyAll() + { + linkFactoryMock.Verify(); + } - private void SetupProjectLinkExpectation() - { - SetupProjectLinkExpectation(projectSpecifier); - } + private void SetupProjectLinkExpectation() + { + SetupProjectLinkExpectation(projectSpecifier); + } - private void SetupProjectLinkExpectation(IProjectSpecifier projectSpecifierForLink) - { + private void SetupProjectLinkExpectation(IProjectSpecifier projectSpecifierForLink) + { linkFactoryMock.SetupResult("CreateProjectLink", projectLink, typeof(IProjectSpecifier), typeof(string)); - } - - [Test] - public void ShouldReturnEmptyListOfRowsWhenNoProjectStatusesAvailable() - { - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[0]; - - Assert.AreEqual(0, projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")).Length); - - VerifyAll(); - } - - [Test] - public void ShouldCopyProjectNameToProjectRow() - { - // Setup - ProjectStatus projectStatus1 = ProjectStatusFixture.New(projectSpecifier.ProjectName); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - - // Execute - SetupProjectLinkExpectation(); - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(1, rows.Length); - Assert.AreEqual(projectSpecifier.ProjectName, rows[0].Name); - VerifyAll(); - } - - [Test] - public void ShouldHandleResultsWithNoBuildLabel() - { - // Setup - ProjectStatus projectStatus1 = ProjectStatusFixture.New(projectSpecifier.ProjectName, null); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - - // Execute - SetupProjectLinkExpectation(); - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(1, rows.Length); - Assert.AreEqual("no build available", rows[0].LastBuildLabel); - VerifyAll(); - } - - [Test] - public void ShouldCopyBuildStatusToProjectRow() - { - // Setup - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Success), serverSpecifier) - }; - - SetupProjectLinkExpectation(); - mocks.ReplayAll(); - - // Execute - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Success", rows[0].BuildStatus); - Assert.AreEqual(Color.Green.Name, rows[0].BuildStatusHtmlColor); - - // Setup - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Failure), serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Failure", rows[0].BuildStatus); - Assert.AreEqual(Color.Red.Name, rows[0].BuildStatusHtmlColor); - - // Setup - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Unknown), serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Unknown", rows[0].BuildStatus); - Assert.AreEqual(Color.Blue.Name, rows[0].BuildStatusHtmlColor); - - // Setup - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Exception), serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Exception", rows[0].BuildStatus); - Assert.AreEqual(Color.Red.Name, rows[0].BuildStatusHtmlColor); - - VerifyAll(); - } - - [Test] - public void ShouldCopyLastBuildDateToProjectRow() - { - // Setup - DateTime date = DateTime.Today; - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Success, date), serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(DateUtil.FormatDate(date), rows[0].LastBuildDate); - VerifyAll(); - } - - [Test] - public void ShouldCopyProjectStatusToProjectRow() - { - // Setup - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", - DateTime.Today, "my label", null, - DateTime.Today, "building", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Running", rows[0].Status); - - VerifyAll(); - - // Setup - projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Stopped, "url", - DateTime.Today, "my label", null, DateTime.Today, "", "", 0, new List()); - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Stopped", rows[0].Status); - VerifyAll(); - } - - [Test] - public void ShouldCopyProjectActivityToProjectRow() - { - // Setup - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", - DateTime.Today, "my label", null, DateTime.Today, "", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("Sleeping", rows[0].Activity); - VerifyAll(); - - // Setup - projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.CheckingModifications, IntegrationStatus.Success, - ProjectIntegratorState.Stopped, "url", DateTime.Today, "my label", - null, DateTime.Today, "", "", 0, new List()); - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, new DefaultServerSpecifier("server")) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("CheckingModifications", rows[0].Activity); - VerifyAll(); - } - - [Test] - public void ShouldCopyLastBuildLabelToProjectRow() - { - // Setup - DateTime date = DateTime.Today; - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", date, - "my label", null, DateTime.Today, "", "", 0, new List()); - - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("my label", rows[0].LastBuildLabel); - VerifyAll(); - } - - [Test] - public void ShouldCreateLinkToProjectReport() - { - // Setup - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", DateTime.Today, - "1", null, DateTime.Today, "", "", 0, new List()); - - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("myLinkUrl", rows[0].Url); - VerifyAll(); - } - - [Test] - public void ShouldDisplayCurrentProjectMessagesInProjectGridRow() - { - // Setup - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", DateTime.Today, - "my label", null, DateTime.Today, "", "", 0, new List()); - - projectStatus1.Messages = new Message[1] {new Message("Test Message")}; - - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.IsNotNull(rows[0].CurrentMessage); - Assert.AreEqual("Test Message", rows[0].CurrentMessage); - VerifyAll(); - - // Setup - projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Stopped, "url", DateTime.Today, - "my label", null, DateTime.Today, "", "", 0, new List()); - - projectStatus1.Messages = new Message[2] {new Message(string.Empty), new Message("Second Message")}; - - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.IsNotNull(rows[0].CurrentMessage); - Assert.AreEqual("Second Message", rows[0].CurrentMessage); - VerifyAll(); - } - - [Test] - public void ShouldCopyProjectCategoryToProjectRow() - { - // Setup - ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", DateTime.Today, - "my label", null, DateTime.Today, "", "", 0, new List()); - - - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("category", rows[0].Category); - VerifyAll(); - - // Setup - projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category1", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Stopped, "url", DateTime.Today, - "my label", null, DateTime.Today, "", "", 0, new List()); - - - statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier) - }; - SetupProjectLinkExpectation(); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual("category1", rows[0].Category); - VerifyAll(); - } - - [Test] - public void ShouldReturnProjectsSortedByNameIfNameColumnSpecifiedAsSortSeed() - { - // Setup - IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); - IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); - - ProjectStatus projectStatus1 = new ProjectStatus("a", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatus2 = new ProjectStatus("b", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier), - new ProjectStatusOnServer(projectStatus2, serverSpecifier) - }; - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("a", rows[0].Name); - Assert.AreEqual("b", rows[1].Name); - - // Setup - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, false, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("b", rows[0].Name); - Assert.AreEqual("a", rows[1].Name); - - VerifyAll(); - } - - [Test] - public void ShouldReturnProjectsSortedByLastBuildDateIfLastBuildDateColumnSpecifiedAsSortSeed() - { - // Setup - IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); - IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); - - ProjectStatus projectStatus1 = new ProjectStatus("b", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", DateTime.Today, - "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatus2 = new ProjectStatus("a", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", - DateTime.Today.AddHours(1), "1", null, - DateTime.Today, "", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier), - new ProjectStatusOnServer(projectStatus2, serverSpecifier) - }; - SetupProjectLinkExpectation(projectB); - SetupProjectLinkExpectation(projectA); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.LastBuildDate, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("b", rows[0].Name); - Assert.AreEqual("a", rows[1].Name); - - // Setup - SetupProjectLinkExpectation(projectB); - SetupProjectLinkExpectation(projectA); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.LastBuildDate, false, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("a", rows[0].Name); - Assert.AreEqual("b", rows[1].Name); - - VerifyAll(); - } - - [Test] - public void ShouldReturnProjectsSortedByBuildStatusIfBuildStatusColumnSpecifiedAsSortSeed() - { - // Setup - IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); - IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); - ProjectStatus projectStatus1 = new ProjectStatus("a", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, - ProjectIntegratorState.Running, "url", DateTime.Today, - "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatus2 = new ProjectStatus("b", "category", - ProjectActivity.Sleeping, IntegrationStatus.Failure, - ProjectIntegratorState.Running, "url", - DateTime.Today.AddHours(1), "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifier), - new ProjectStatusOnServer(projectStatus2, serverSpecifier) - }; - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.BuildStatus, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("b", rows[0].Name); - Assert.AreEqual("a", rows[1].Name); - - // Setup - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.BuildStatus, false, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("a", rows[0].Name); - Assert.AreEqual("b", rows[1].Name); - - VerifyAll(); - } - - [Test] - public void ShouldReturnProjectsSortedByServerIfServerNameColumnSpecifiedAsSortSeed() - { - // Setup - IServerSpecifier serverSpecifierA = new DefaultServerSpecifier("Aserver"); - IServerSpecifier serverSpecifierB = new DefaultServerSpecifier("Bserver"); - IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifierA, "a"); - IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifierB, "b"); - - ProjectStatus projectStatus1 = new ProjectStatus("a", "category", - ProjectActivity.Sleeping, IntegrationStatus.Success, ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatus2 = new ProjectStatus("b", "category", - ProjectActivity.Sleeping, IntegrationStatus.Failure, ProjectIntegratorState.Running, "url", - DateTime.Today.AddHours(1), "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatus1, serverSpecifierA), - new ProjectStatusOnServer(projectStatus2, serverSpecifierB) - }; - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.ServerName, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("a", rows[0].Name); - Assert.AreEqual("b", rows[1].Name); - - // Setup - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - - // Execute - rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.ServerName, false, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(2, rows.Length); - Assert.AreEqual("b", rows[0].Name); - Assert.AreEqual("a", rows[1].Name); - - VerifyAll(); - } - - [Test] - public void ShouldReturnProjectsSortedByCategoryIfCategoryColumnSpecifiedAsSortSeed() - { - // Setup - IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "A"); - IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "B"); - IProjectSpecifier projectC = new DefaultProjectSpecifier(serverSpecifier, "C"); - - ProjectStatus projectStatusA = new ProjectStatus("A", "CategoryX", ProjectActivity.Sleeping, - IntegrationStatus.Success, ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatusB = new ProjectStatus("B", "CategoryY", ProjectActivity.Sleeping, - IntegrationStatus.Success, ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - ProjectStatus projectStatusC = new ProjectStatus("C", "CategoryX", ProjectActivity.Sleeping, - IntegrationStatus.Success, ProjectIntegratorState.Running, "url", - DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); - - ProjectStatusOnServer[] status = new ProjectStatusOnServer[] - { - new ProjectStatusOnServer(projectStatusA, serverSpecifier), - new ProjectStatusOnServer(projectStatusB, serverSpecifier), - new ProjectStatusOnServer(projectStatusC, serverSpecifier) - }; - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - SetupProjectLinkExpectation(projectC); - - // Execute - mocks.ReplayAll(); - mocks.ReplayAll(); - ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(status, "myAction", ProjectGridSortColumn.Category, true, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(3, rows.Length); - Assert.AreEqual("A", rows[0].Name); - Assert.AreEqual("C", rows[1].Name); - Assert.AreEqual("B", rows[2].Name); - - // Setup - SetupProjectLinkExpectation(projectA); - SetupProjectLinkExpectation(projectB); - SetupProjectLinkExpectation(projectC); - - // Execute - rows = projectGrid.GenerateProjectGridRows(status, "myAction", ProjectGridSortColumn.Category, false, "", urlBuilderMock, new Translations("en-US")); - - // Verify - Assert.AreEqual(3, rows.Length); - Assert.AreEqual("B", rows[0].Name); - Assert.AreEqual("A", rows[1].Name); - Assert.AreEqual("C", rows[2].Name); - - VerifyAll(); - } - } + } + + //[Test] + //public void ShouldReturnEmptyListOfRowsWhenNoProjectStatusesAvailable() + //{ + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[0]; + + // Assert.AreEqual(0, projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")).Length); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyProjectNameToProjectRow() + //{ + // // Setup + // ProjectStatus projectStatus1 = ProjectStatusFixture.New(projectSpecifier.ProjectName); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + + // // Execute + // SetupProjectLinkExpectation(); + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(1, rows.Length); + // Assert.AreEqual(projectSpecifier.ProjectName, rows[0].Name); + // VerifyAll(); + //} + + //[Test] + //public void ShouldHandleResultsWithNoBuildLabel() + //{ + // // Setup + // ProjectStatus projectStatus1 = ProjectStatusFixture.New(projectSpecifier.ProjectName, null); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + + // // Execute + // SetupProjectLinkExpectation(); + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(1, rows.Length); + // Assert.AreEqual("no build available", rows[0].LastBuildLabel); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyBuildStatusToProjectRow() + //{ + // // Setup + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Success), serverSpecifier) + // }; + + // SetupProjectLinkExpectation(); + // mocks.ReplayAll(); + + // // Execute + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Success", rows[0].BuildStatus); + // Assert.AreEqual(Color.Green.Name, rows[0].BuildStatusHtmlColor); + + // // Setup + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Failure), serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Failure", rows[0].BuildStatus); + // Assert.AreEqual(Color.Red.Name, rows[0].BuildStatusHtmlColor); + + // // Setup + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Unknown), serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Unknown", rows[0].BuildStatus); + // Assert.AreEqual(Color.Blue.Name, rows[0].BuildStatusHtmlColor); + + // // Setup + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Exception), serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Exception", rows[0].BuildStatus); + // Assert.AreEqual(Color.Red.Name, rows[0].BuildStatusHtmlColor); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyLastBuildDateToProjectRow() + //{ + // // Setup + // DateTime date = DateTime.Today; + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(ProjectStatusFixture.New(projectSpecifier.ProjectName, IntegrationStatus.Success, date), serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(DateUtil.FormatDate(date), rows[0].LastBuildDate); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyProjectStatusToProjectRow() + //{ + // // Setup + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", + // DateTime.Today, "my label", null, + // DateTime.Today, "building", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Running", rows[0].Status); + + // VerifyAll(); + + // // Setup + // projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Stopped, "url", + // DateTime.Today, "my label", null, DateTime.Today, "", "", 0, new List()); + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Stopped", rows[0].Status); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyProjectActivityToProjectRow() + //{ + // // Setup + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", + // DateTime.Today, "my label", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("Sleeping", rows[0].Activity); + // VerifyAll(); + + // // Setup + // projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.CheckingModifications, IntegrationStatus.Success, + // ProjectIntegratorState.Stopped, "url", DateTime.Today, "my label", + // null, DateTime.Today, "", "", 0, new List()); + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, new DefaultServerSpecifier("server")) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("CheckingModifications", rows[0].Activity); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyLastBuildLabelToProjectRow() + //{ + // // Setup + // DateTime date = DateTime.Today; + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", date, + // "my label", null, DateTime.Today, "", "", 0, new List()); + + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("my label", rows[0].LastBuildLabel); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCreateLinkToProjectReport() + //{ + // // Setup + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", DateTime.Today, + // "1", null, DateTime.Today, "", "", 0, new List()); + + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("myLinkUrl", rows[0].Url); + // VerifyAll(); + //} + + //[Test] + //public void ShouldDisplayCurrentProjectMessagesInProjectGridRow() + //{ + // // Setup + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", DateTime.Today, + // "my label", null, DateTime.Today, "", "", 0, new List()); + + // projectStatus1.Messages = new Message[1] {new Message("Test Message")}; + + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.IsNotNull(rows[0].CurrentMessage); + // Assert.AreEqual("Test Message", rows[0].CurrentMessage); + // VerifyAll(); + + // // Setup + // projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Stopped, "url", DateTime.Today, + // "my label", null, DateTime.Today, "", "", 0, new List()); + + // projectStatus1.Messages = new Message[2] {new Message(string.Empty), new Message("Second Message")}; + + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.IsNotNull(rows[0].CurrentMessage); + // Assert.AreEqual("Second Message", rows[0].CurrentMessage); + // VerifyAll(); + //} + + //[Test] + //public void ShouldCopyProjectCategoryToProjectRow() + //{ + // // Setup + // ProjectStatus projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", DateTime.Today, + // "my label", null, DateTime.Today, "", "", 0, new List()); + + + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("category", rows[0].Category); + // VerifyAll(); + + // // Setup + // projectStatus1 = new ProjectStatus(projectSpecifier.ProjectName, "category1", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Stopped, "url", DateTime.Today, + // "my label", null, DateTime.Today, "", "", 0, new List()); + + + // statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier) + // }; + // SetupProjectLinkExpectation(); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual("category1", rows[0].Category); + // VerifyAll(); + //} + + //[Test] + //public void ShouldReturnProjectsSortedByNameIfNameColumnSpecifiedAsSortSeed() + //{ + // // Setup + // IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); + // IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); + + // ProjectStatus projectStatus1 = new ProjectStatus("a", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatus2 = new ProjectStatus("b", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier), + // new ProjectStatusOnServer(projectStatus2, serverSpecifier) + // }; + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("a", rows[0].Name); + // Assert.AreEqual("b", rows[1].Name); + + // // Setup + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.Name, false, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("b", rows[0].Name); + // Assert.AreEqual("a", rows[1].Name); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldReturnProjectsSortedByLastBuildDateIfLastBuildDateColumnSpecifiedAsSortSeed() + //{ + // // Setup + // IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); + // IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); + + // ProjectStatus projectStatus1 = new ProjectStatus("b", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", DateTime.Today, + // "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatus2 = new ProjectStatus("a", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", + // DateTime.Today.AddHours(1), "1", null, + // DateTime.Today, "", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier), + // new ProjectStatusOnServer(projectStatus2, serverSpecifier) + // }; + // SetupProjectLinkExpectation(projectB); + // SetupProjectLinkExpectation(projectA); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.LastBuildDate, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("b", rows[0].Name); + // Assert.AreEqual("a", rows[1].Name); + + // // Setup + // SetupProjectLinkExpectation(projectB); + // SetupProjectLinkExpectation(projectA); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.LastBuildDate, false, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("a", rows[0].Name); + // Assert.AreEqual("b", rows[1].Name); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldReturnProjectsSortedByBuildStatusIfBuildStatusColumnSpecifiedAsSortSeed() + //{ + // // Setup + // IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "a"); + // IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "b"); + // ProjectStatus projectStatus1 = new ProjectStatus("a", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, + // ProjectIntegratorState.Running, "url", DateTime.Today, + // "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatus2 = new ProjectStatus("b", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Failure, + // ProjectIntegratorState.Running, "url", + // DateTime.Today.AddHours(1), "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifier), + // new ProjectStatusOnServer(projectStatus2, serverSpecifier) + // }; + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.BuildStatus, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("b", rows[0].Name); + // Assert.AreEqual("a", rows[1].Name); + + // // Setup + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.BuildStatus, false, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("a", rows[0].Name); + // Assert.AreEqual("b", rows[1].Name); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldReturnProjectsSortedByServerIfServerNameColumnSpecifiedAsSortSeed() + //{ + // // Setup + // IServerSpecifier serverSpecifierA = new DefaultServerSpecifier("Aserver"); + // IServerSpecifier serverSpecifierB = new DefaultServerSpecifier("Bserver"); + // IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifierA, "a"); + // IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifierB, "b"); + + // ProjectStatus projectStatus1 = new ProjectStatus("a", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Success, ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatus2 = new ProjectStatus("b", "category", + // ProjectActivity.Sleeping, IntegrationStatus.Failure, ProjectIntegratorState.Running, "url", + // DateTime.Today.AddHours(1), "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatusOnServer[] statusses = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatus1, serverSpecifierA), + // new ProjectStatusOnServer(projectStatus2, serverSpecifierB) + // }; + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.ServerName, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("a", rows[0].Name); + // Assert.AreEqual("b", rows[1].Name); + + // // Setup + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(statusses, "myAction", ProjectGridSortColumn.ServerName, false, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(2, rows.Length); + // Assert.AreEqual("b", rows[0].Name); + // Assert.AreEqual("a", rows[1].Name); + + // VerifyAll(); + //} + + //[Test] + //public void ShouldReturnProjectsSortedByCategoryIfCategoryColumnSpecifiedAsSortSeed() + //{ + // // Setup + // IProjectSpecifier projectA = new DefaultProjectSpecifier(serverSpecifier, "A"); + // IProjectSpecifier projectB = new DefaultProjectSpecifier(serverSpecifier, "B"); + // IProjectSpecifier projectC = new DefaultProjectSpecifier(serverSpecifier, "C"); + + // ProjectStatus projectStatusA = new ProjectStatus("A", "CategoryX", ProjectActivity.Sleeping, + // IntegrationStatus.Success, ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatusB = new ProjectStatus("B", "CategoryY", ProjectActivity.Sleeping, + // IntegrationStatus.Success, ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + // ProjectStatus projectStatusC = new ProjectStatus("C", "CategoryX", ProjectActivity.Sleeping, + // IntegrationStatus.Success, ProjectIntegratorState.Running, "url", + // DateTime.Today, "1", null, DateTime.Today, "", "", 0, new List()); + + // ProjectStatusOnServer[] status = new ProjectStatusOnServer[] + // { + // new ProjectStatusOnServer(projectStatusA, serverSpecifier), + // new ProjectStatusOnServer(projectStatusB, serverSpecifier), + // new ProjectStatusOnServer(projectStatusC, serverSpecifier) + // }; + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + // SetupProjectLinkExpectation(projectC); + + // // Execute + // mocks.ReplayAll(); + // mocks.ReplayAll(); + // ProjectGridRow[] rows = projectGrid.GenerateProjectGridRows(status, "myAction", ProjectGridSortColumn.Category, true, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(3, rows.Length); + // Assert.AreEqual("A", rows[0].Name); + // Assert.AreEqual("C", rows[1].Name); + // Assert.AreEqual("B", rows[2].Name); + + // // Setup + // SetupProjectLinkExpectation(projectA); + // SetupProjectLinkExpectation(projectB); + // SetupProjectLinkExpectation(projectC); + + // // Execute + // rows = projectGrid.GenerateProjectGridRows(status, "myAction", ProjectGridSortColumn.Category, false, "", urlBuilderMock, new Translations("en-US")); + + // // Verify + // Assert.AreEqual(3, rows.Length); + // Assert.AreEqual("B", rows[0].Name); + // Assert.AreEqual("A", rows[1].Name); + // Assert.AreEqual("C", rows[2].Name); + + // VerifyAll(); + //} + } } diff --git a/project/WebDashboard/Dashboard/DataGridRow.cs b/project/WebDashboard/Dashboard/DataGridRow.cs new file mode 100644 index 000000000..59ad824fe --- /dev/null +++ b/project/WebDashboard/Dashboard/DataGridRow.cs @@ -0,0 +1,28 @@ +using System; +using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; +using ThoughtWorks.CruiseControl.Core.Util; +using ThoughtWorks.CruiseControl.Remote; +using ThoughtWorks.CruiseControl.WebDashboard.Resources; + +namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard +{ + public class DataGridRow + { + private readonly string buildStatus; + private readonly string date; + private readonly string link; + + public DataGridRow(string buildStatus, string date, string link) + { + this.buildStatus = buildStatus; + this.date = date; + this.link = link; + } + + public string BuildStatus { get { return buildStatus; } } + + public string Date { get { return date; } } + + public string Link { get { return link; } } + } +} diff --git a/project/WebDashboard/Dashboard/IProjectGrid.cs b/project/WebDashboard/Dashboard/IProjectGrid.cs index 8ab2a6394..a3ce10f79 100644 --- a/project/WebDashboard/Dashboard/IProjectGrid.cs +++ b/project/WebDashboard/Dashboard/IProjectGrid.cs @@ -4,14 +4,8 @@ namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard { - public interface IProjectGrid - { - ProjectGridRow[] GenerateProjectGridRows(ProjectStatusOnServer[] statusList, - string forceBuildActionName, - ProjectGridSortColumn sortColumn, - bool sortIsAscending, - string categoryFilter, - ICruiseUrlBuilder urlBuilder, - Translations translations); - } + public interface IProjectGrid + { + ProjectGridRow[] GenerateProjectGridRows(ProjectGridParameters parameters); + } } diff --git a/project/WebDashboard/Dashboard/ProjectGrid.cs b/project/WebDashboard/Dashboard/ProjectGrid.cs index 9e676b831..d4d70c0dc 100644 --- a/project/WebDashboard/Dashboard/ProjectGrid.cs +++ b/project/WebDashboard/Dashboard/ProjectGrid.cs @@ -1,84 +1,250 @@ +using System; +using System.Configuration; using System.Collections.Generic; +using System.IO; +using System.Xml; +using System.Xml.Linq; using System.Linq; using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; using ThoughtWorks.CruiseControl.Remote; using ThoughtWorks.CruiseControl.WebDashboard.Plugins.ProjectReport; using ThoughtWorks.CruiseControl.WebDashboard.Resources; using ThoughtWorks.CruiseControl.WebDashboard.ServerConnection; +using ThoughtWorks.CruiseControl.WebDashboard.Plugins.BuildReport; +using ThoughtWorks.CruiseControl.Core.Queues; +using ThoughtWorks.CruiseControl.Core.Config; +using ThoughtWorks.CruiseControl.Core; +using ThoughtWorks.CruiseControl.WebDashboard.IO; +using ThoughtWorks.CruiseControl.Remote.Parameters; namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard { public class ProjectGrid : IProjectGrid - { - public ProjectGridRow[] GenerateProjectGridRows(ProjectStatusOnServer[] statusList, string forceBuildActionName, - ProjectGridSortColumn sortColumn, bool sortIsAscending, string categoryFilter, - ICruiseUrlBuilder urlBuilder, Translations translations) - { - var rows = new List(); - foreach (ProjectStatusOnServer statusOnServer in statusList) - { - ProjectStatus status = statusOnServer.ProjectStatus; - IServerSpecifier serverSpecifier = statusOnServer.ServerSpecifier; - DefaultProjectSpecifier projectSpecifier = new DefaultProjectSpecifier(serverSpecifier, status.Name); - - if ((categoryFilter != string.Empty) && (categoryFilter != status.Category)) - continue; - - rows.Add( - new ProjectGridRow(status, - serverSpecifier, - urlBuilder.BuildProjectUrl(ProjectReportProjectPlugin.ACTION_NAME, projectSpecifier), - urlBuilder.BuildProjectUrl(ProjectParametersAction.ActionName, projectSpecifier), - translations)); - } - - return rows.OrderBy(a => a, GetComparer(sortColumn, sortIsAscending)).ToArray(); - } - - private IComparer GetComparer(ProjectGridSortColumn column, bool ascending) - { - return new ProjectGridRowComparer(column, ascending); - } - - private class ProjectGridRowComparer + { + public ProjectGridRow[] GenerateProjectGridRows(ProjectGridParameters parameters) + { + var rows = new List(); + var farmService = parameters.FarmService; + string disk = new AppSettingsReader().GetValue("disk", typeof(System.String)).ToString(); + string server = new AppSettingsReader().GetValue("framework", typeof(System.String)).ToString(); + + foreach (ProjectStatusOnServer statusOnServer in parameters.StatusList) + { + ProjectStatus status = statusOnServer.ProjectStatus; + IServerSpecifier serverSpecifier = statusOnServer.ServerSpecifier; + DefaultProjectSpecifier projectSpecifier = new DefaultProjectSpecifier(serverSpecifier, status.Name); + + if ((parameters.CategoryFilter != string.Empty) && (parameters.CategoryFilter != status.Category)) + continue; + + string dir = disk + server + @"\"; + string statistics = ""; + string runningTime = String.Empty; + + if (Directory.Exists(dir)) + { + var file = String.Format(@"{0}{1}\ccnet\{2}\TestResults.html", dir, serverSpecifier.ServerName, projectSpecifier.ProjectName); + var fileRunningTime = String.Format(@"{0}{1}\ccnet\{2}\RunningTime.html", dir, serverSpecifier.ServerName, projectSpecifier.ProjectName); + try + { + if (File.Exists(file)) + statistics = File.ReadAllText(file); + + if (File.Exists(fileRunningTime)) + runningTime = File.ReadAllText(fileRunningTime); + + if (!File.Exists(fileRunningTime) || runningTime.Length < 1) + runningTime = readRunningTimeIfFileEmpty(farmService, projectSpecifier, serverSpecifier, dir); + } + catch (Exception e) + { + statistics = String.Format("", e.Message.Replace("-->", "- - >")); + runningTime = String.Format("", e.Message.Replace("-->", "- - >")); + } + } + + var queuePosition = getQueuePosition(status, serverSpecifier, projectSpecifier, farmService); + var buildParameters = status.Parameters; + var brokenDays = brokenTime(serverSpecifier, projectSpecifier, dir, farmService, status); + rows.Add(new ProjectGridRow(status, + serverSpecifier, + parameters.UrlBuilder.BuildProjectUrl(ProjectReportProjectPlugin.ACTION_NAME, projectSpecifier), + parameters.UrlBuilder.BuildProjectUrl(ProjectParametersAction.ActionName, projectSpecifier), + statistics, + runningTime, + queuePosition, + buildParameters, + brokenDays, + parameters.Translation)); + } + + rows.Sort(GetComparer(parameters.SortColumn, parameters.SortIsAscending)); + return rows.ToArray(); + } + + private IComparer GetComparer(ProjectGridSortColumn column, bool ascending) + { + return new ProjectGridRowComparer(column, ascending); + } + + private class ProjectGridRowComparer : IComparer - { - private readonly ProjectGridSortColumn column; - private readonly bool ascending; + { + private readonly ProjectGridSortColumn column; + private readonly bool ascending; - public ProjectGridRowComparer(ProjectGridSortColumn column, bool ascending) - { - this.column = column; - this.ascending = ascending; - } + public ProjectGridRowComparer(ProjectGridSortColumn column, bool ascending) + { + this.column = column; + this.ascending = ascending; + } public int Compare(ProjectGridRow x, ProjectGridRow y) - { - if (column == ProjectGridSortColumn.Name) - { - return x.Name.CompareTo(y.Name)*(ascending ? 1 : -1); - } - else if (column == ProjectGridSortColumn.LastBuildDate) - { - return x.LastBuildDate.CompareTo(y.LastBuildDate)*(ascending ? 1 : -1); - } - else if (column == ProjectGridSortColumn.BuildStatus) - { - return x.BuildStatus.CompareTo(y.BuildStatus)*(ascending ? 1 : -1); - } - else if (column == ProjectGridSortColumn.ServerName) - { - return x.ServerName.CompareTo(y.ServerName)*(ascending ? 1 : -1); - } - else if (column == ProjectGridSortColumn.Category) + { + if (column == ProjectGridSortColumn.Name) + { + return x.Name.CompareTo(y.Name) * (ascending ? 1 : -1); + } + else if (column == ProjectGridSortColumn.LastBuildDate) + { + return x.LastBuildDate.CompareTo(y.LastBuildDate) * (ascending ? 1 : -1); + } + else if (column == ProjectGridSortColumn.BuildStatus) + { + return x.BuildStatus.CompareTo(y.BuildStatus) * (ascending ? 1 : -1); + } + else if (column == ProjectGridSortColumn.ServerName) + { + return x.ServerName.CompareTo(y.ServerName) * (ascending ? 1 : -1); + } + else if (column == ProjectGridSortColumn.Category) + { + return x.Category.CompareTo(y.Category) * (ascending ? 1 : -1); + } + else + { + return 0; + } + } + } + + private string readRunningTimeIfFileEmpty(IFarmService farmService, DefaultProjectSpecifier projectSpecifier, IServerSpecifier serverSpecifier, string dir) + { + IBuildSpecifier[] mostRecentBuildSpecifiers = farmService.GetMostRecentBuildSpecifiers(projectSpecifier, 1, BuildReportBuildPlugin.ACTION_NAME); + var buildFile = String.Format(@"{0}{1}\ccnet\{2}\Artifacts\buildlogs\{3}", dir, serverSpecifier.ServerName, projectSpecifier.ProjectName, mostRecentBuildSpecifiers[0].BuildName); + var doc = XDocument.Load(buildFile); + IEnumerable elemList = doc.Descendants("build"); + if (Directory.Exists(buildFile)) + { + foreach (var node in elemList) + { + return (string)node.Attribute("buildtime"); + } + } + return String.Empty; + } + + private DataGridRow getBuildData(IServerSpecifier serverSpecifier, DefaultProjectSpecifier projectSpecifier, string dir, ProjectStatus status, + IBuildSpecifier buildSpecifier, bool first) + { + DataGridRow dataToReturn; + string buildName = buildSpecifier.BuildName; + string lastStatus = ""; + if (first) + { + lastStatus = status.BuildStatus.ToString(); + } + else + { + if (buildName.Contains("Lbuild")) { lastStatus = "Success"; } + else { lastStatus = "Failure"; } + } + string lastDate = String.Format("{0}-{1}-{2} {3}:{4}:{5}", buildName.Substring(3, 4), buildName.Substring(7, 2), buildName.Substring(9, 2), + buildName.Substring(11, 2), buildName.Substring(13, 2), buildName.Substring(15, 2)); + string lastLink = String.Format("http://{0}/ccnet/server/{0}/project/{1}/build/{2}/ViewBuildReport.aspx", + serverSpecifier.ServerName, projectSpecifier.ProjectName, buildName); + dataToReturn = new DataGridRow(lastStatus, lastDate, lastLink); + return dataToReturn; + } + + private int getQueuePosition(ProjectStatus status, IServerSpecifier serverSpecifier, DefaultProjectSpecifier projectSpecifier, IFarmService farmService) + { + if (status.Activity.ToString().Equals("Pending")) + { + return getPositionInQueueList(status, serverSpecifier, projectSpecifier, farmService); + } + return -1; + } + + private int getPositionInQueueList(ProjectStatus status, IServerSpecifier serverSpecifier, DefaultProjectSpecifier projectSpecifier, IFarmService farmService) + { + CruiseServerSnapshotListAndExceptions snapshot = farmService.GetCruiseServerSnapshotListAndExceptions(serverSpecifier, string.Empty); + List queues = new List(); + + foreach (CruiseServerSnapshot cruiseServerSnapshot in snapshot.Snapshots) + { + QueueSetSnapshot queueSnapshot = cruiseServerSnapshot.QueueSetSnapshot; + foreach (QueueSnapshot queueSnapshotItem in queueSnapshot.Queues) + { + var index = checkPositionQueue(queueSnapshotItem, projectSpecifier); + if (index > -1) { return index; } + } + } + return -1; + } + + private int checkPositionQueue(QueueSnapshot queueSnapshotItem, DefaultProjectSpecifier projectSpecifier) + { + for (int i = 0; i < queueSnapshotItem.Requests.Count; i++) + { + if (queueSnapshotItem.Requests[i].ProjectName == projectSpecifier.ProjectName) + { + return i; + } + } + return -1; + } + + private string brokenTime(IServerSpecifier serverSpecifier, DefaultProjectSpecifier projectSpecifier, string dir, IFarmService farmService, ProjectStatus status) + { + DataGridRow helper; + DateTime dateFailure = DateTime.Now; + DateTime today = DateTime.Now; + bool first = true; + string dirPath = String.Format(@"{0}{1}\ccnet\{2}\Artifacts\buildlogs", dir, serverSpecifier.ServerName, projectSpecifier.ProjectName); + if (Directory.Exists(dirPath)) + { + var mostRecentBuildSpecifiers = farmService.GetMostRecentBuildSpecifiers(projectSpecifier, Directory.GetFiles(dirPath).Length, BuildReportBuildPlugin.ACTION_NAME); + foreach (IBuildSpecifier buildSpecifier in mostRecentBuildSpecifiers) { - return x.Category.CompareTo(y.Category)*(ascending ? 1 : -1); - } - else - { - return 0; - } - } - } - } + helper = getBuildData(serverSpecifier, projectSpecifier, dir, status, buildSpecifier, first); + if (helper.BuildStatus.Equals("Failure")) + { + dateFailure = DateTime.ParseExact(helper.Date, "yyyy-MM-dd HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); + } + else + { + break; + } + first = false; + } + } + if (Math.Floor((today - dateFailure).TotalDays) < 1) + { + if (Math.Floor((today - dateFailure).TotalHours) < 1) + return "<1 Hour"; + else if (Math.Floor((today - dateFailure).TotalHours) == 1) + return "1 Hour"; + else + return String.Format("{0} Hours", Math.Floor((today - dateFailure).TotalHours)); + } + else + { + if (Math.Floor((today - dateFailure).TotalDays) == 1) + return "1 Day"; + else + return String.Format("{0} Days", Math.Floor((today - dateFailure).TotalDays)); + } + } + } } diff --git a/project/WebDashboard/Dashboard/ProjectGridParameters.cs b/project/WebDashboard/Dashboard/ProjectGridParameters.cs new file mode 100644 index 000000000..0e89ae454 --- /dev/null +++ b/project/WebDashboard/Dashboard/ProjectGridParameters.cs @@ -0,0 +1,46 @@ +using System; +using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; +using ThoughtWorks.CruiseControl.Core.Util; +using ThoughtWorks.CruiseControl.Remote; +using ThoughtWorks.CruiseControl.WebDashboard.Resources; +using ThoughtWorks.CruiseControl.WebDashboard.ServerConnection; + +namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard +{ + public class ProjectGridParameters + { + private readonly ProjectStatusOnServer[] statusList; + private readonly ProjectGridSortColumn sortColumn; + private readonly bool sortIsAscending; + private readonly string categoryFilter; + private readonly ICruiseUrlBuilder urlBuilder; + private readonly IFarmService farmService; + private readonly Translations translation; + + public ProjectGridParameters(ProjectStatusOnServer[] statusList, ProjectGridSortColumn sortColumn, bool sortIsAscending, string categoryFilter, + ICruiseUrlBuilder urlBuilder, IFarmService farmService, Translations translation) + { + this.statusList = statusList; + this.sortColumn = sortColumn; + this.sortIsAscending = sortIsAscending; + this.categoryFilter = categoryFilter; + this.urlBuilder = urlBuilder; + this.farmService = farmService; + this.translation = translation; + } + + public ProjectStatusOnServer[] StatusList { get { return statusList; } } + + public ProjectGridSortColumn SortColumn { get { return sortColumn; } } + + public bool SortIsAscending { get { return sortIsAscending; } } + + public string CategoryFilter { get { return categoryFilter; } } + + public ICruiseUrlBuilder UrlBuilder { get { return urlBuilder; } } + + public IFarmService FarmService { get { return farmService; } } + + public Translations Translation { get { return translation; } } + } +} diff --git a/project/WebDashboard/Dashboard/ProjectGridRow.cs b/project/WebDashboard/Dashboard/ProjectGridRow.cs index aeaa08aae..ec3f874dd 100644 --- a/project/WebDashboard/Dashboard/ProjectGridRow.cs +++ b/project/WebDashboard/Dashboard/ProjectGridRow.cs @@ -1,8 +1,10 @@ using System; +using System.Collections.Generic; using System.Drawing; using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; using ThoughtWorks.CruiseControl.Core.Util; using ThoughtWorks.CruiseControl.Remote; +using ThoughtWorks.CruiseControl.Remote.Parameters; using ThoughtWorks.CruiseControl.WebDashboard.Resources; namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard @@ -13,6 +15,11 @@ public class ProjectGridRow private readonly IServerSpecifier serverSpecifier; private readonly string url; private readonly string parametersUrl; + private readonly string statistics; + private readonly string runningTime; + private readonly List buildParameters; + private readonly int queuePosition; + private readonly string brokenTime; public ProjectGridRow(ProjectStatus status, IServerSpecifier serverSpecifier, string url, string parametersUrl, Translations translations) @@ -23,167 +30,113 @@ public ProjectGridRow(ProjectStatus status, IServerSpecifier serverSpecifier, this.parametersUrl = parametersUrl; } - public string Name + public ProjectGridRow(ProjectStatus status, IServerSpecifier serverSpecifier, + string url, string parametersUrl, string statistics, string runningTime, + int queuePosition, List buildParameters, string brokenTime, Translations translations) + : this(status, serverSpecifier, url, parametersUrl, translations) { - get { return status.Name; } + this.statistics = statistics; + this.runningTime = runningTime; + this.queuePosition = queuePosition; + this.buildParameters = buildParameters; + this.brokenTime = brokenTime; } - public string Description - { - get - { - if (String.IsNullOrEmpty(status.Description)) return ""; + public string Name { get { return status.Name; } } - return status.Description; - } - } + public string ServerName { get { return serverSpecifier.ServerName; } } + public string Category { get { return status.Category; } } - public string ServerName - { - get { return serverSpecifier.ServerName; } - } + public string BuildStatus { get { return status.BuildStatus.ToString(); } } - public string Category - { - get { return status.Category; } - } + public string BuildStatusHtmlColor { get { return CalculateHtmlColor(status.BuildStatus); } } - public string BuildStatus - { - get { return status.BuildStatus.ToString(); } - } + public string LastBuildDate { get { return DateUtil.FormatDate(status.LastBuildDate); } } - public string BuildStatusHtmlColor - { - get { return CalculateHtmlColor(status.BuildStatus); } - } + public string LastBuildLabel { get { return (status.LastBuildLabel != null ? status.LastBuildLabel : "no build available"); } } - public string LastBuildDate - { - get { return DateUtil.FormatDate(status.LastBuildDate); } - } + public string Status { get { return status.Status.ToString(); } } - public string NextBuildTime - { - get - { - if (status.NextBuildTime == System.DateTime.MaxValue) - { - return "Force Build Only"; - } - else - { - return DateUtil.FormatDate(status.NextBuildTime); - } - } - } + public string Activity { get { return status.Activity.ToString(); } } - public string LastBuildLabel - { - get { return (status.LastBuildLabel != null ? status.LastBuildLabel : "no build available"); } - } + public string CurrentMessage { get { return status.CurrentMessage; } } - public string Status - { - get { return status.Status.ToString(); } - } + public string Breakers { get { return GetMessageText(Message.MessageKind.Breakers); } } - public string Activity - { - get { return status.Activity.ToString(); } - } + public string FailingTasks { get { return GetMessageText(Message.MessageKind.FailingTasks); } } - public string CurrentMessage - { - get { return status.CurrentMessage; } - } + public string Fixer { get { return GetMessageText(Message.MessageKind.Fixer); } } - public string Breakers - { - get - { - return GetMessageText(Message.MessageKind.Breakers); - } - } + public string ForceBuildPublisher { get { return GetMessageText(Message.MessageKind.ForceBuildPublisherFailed); } } - public string FailingTasks - { - get - { - return GetMessageText(Message.MessageKind.FailingTasks); - } - } + public string Url { get { return url; } } - public string Fixer - { - get - { - return GetMessageText(Message.MessageKind.Fixer); - } - } + public string Queue { get { return status.Queue; } } - public string Url - { - get { return url; } - } + public int QueuePriority { get { return status.QueuePriority; } } + public int QueuePosition { get { return queuePosition; } } - public string Queue - { - get { return status.Queue; } - } + public string StartStopButtonName { get { return (status.Status == ProjectIntegratorState.Running) ? "StopBuild" : "StartBuild"; } } + public string StartStopButtonValue { get { return (status.Status == ProjectIntegratorState.Running) ? "Stop" : "Start"; } } - public int QueuePriority - { - get { return status.QueuePriority; } - } + public string ForceAbortBuildButtonName { get { return (status.Activity != ProjectActivity.Building) ? "ForceBuild" : "AbortBuild"; } } + public string ForceAbortBuildButtonValue { get { return (status.Activity != ProjectActivity.Building) ? "Force" : "Abort"; } } - public string StartStopButtonName - { - get { return (status.Status == ProjectIntegratorState.Running) ? "StopBuild" : "StartBuild"; } - } + public string CancelPendingButtonName { get { return (status.Activity == ProjectActivity.Pending) ? "CancelPending" : string.Empty; } } - public string StartStopButtonValue - { - get { return (status.Status == ProjectIntegratorState.Running) ? "Stop" : "Start"; } - } + public bool AllowForceBuild { get { return serverSpecifier.AllowForceBuild && status.ShowForceBuildButton; } } - public string ForceAbortBuildButtonName - { - get { return (status.Activity != ProjectActivity.Building) ? "ForceBuild" : "AbortBuild"; } - } + public bool AllowStartStopBuild { get { return serverSpecifier.AllowStartStopBuild && status.ShowStartStopButton; } } - public string ForceAbortBuildButtonValue - { - get { return (status.Activity != ProjectActivity.Building) ? "Force" : "Abort"; } - } + public string Statistics { get { return this.statistics; } } - public bool AllowForceBuild - { - get { return serverSpecifier.AllowForceBuild && status.ShowForceBuildButton; } - } + public string RunningTime { get { return this.runningTime; } } - public bool AllowStartStopBuild - { - get { return serverSpecifier.AllowStartStopBuild && status.ShowStartStopButton; } - } + public string ParametersUrl { get { return parametersUrl; } } - private string CalculateHtmlColor(IntegrationStatus integrationStatus) + public List BuildParameters { get { return buildParameters; } } + + public int BuildParametersCount { get { return buildParameters.Count; } } + + public string BrokenTime { get { return brokenTime; } } + + public string[] BreakersNames { - if (integrationStatus == IntegrationStatus.Success) + get { - return Color.Green.Name; + string text = GetMessageText(Message.MessageKind.Breakers); + text = System.Text.RegularExpressions.Regex.Replace(text, ",.", "/", System.Text.RegularExpressions.RegexOptions.None); + var users = text.Split('/'); + return users; } - else if (integrationStatus == IntegrationStatus.Unknown) + } + + public string Description + { + get { - return Color.Blue.Name; + if (String.IsNullOrEmpty(status.Description)) return ""; + + return status.Description; } - else + } + + public string NextBuildTime + { + get { - return Color.Red.Name; + if (status.NextBuildTime == System.DateTime.MaxValue) + { + return "Force Build Only"; + } + else + { + return DateUtil.FormatDate(status.NextBuildTime); + } } } @@ -204,12 +157,22 @@ public string BuildStage } } - public string ParametersUrl + private string CalculateHtmlColor(IntegrationStatus integrationStatus) { - get { return parametersUrl; } + if (integrationStatus == IntegrationStatus.Success) + { + return Color.Green.Name; + } + else if (integrationStatus == IntegrationStatus.Unknown) + { + return Color.Blue.Name; + } + else + { + return Color.Red.Name; + } } - private string GetMessageText(Message.MessageKind messageType) { foreach (Message m in status.Messages) @@ -220,7 +183,6 @@ private string GetMessageText(Message.MessageKind messageType) } } return string.Empty; - } } } diff --git a/project/WebDashboard/Dashboard/VelocityProjectGridAction.cs b/project/WebDashboard/Dashboard/VelocityProjectGridAction.cs index 975b3cb04..d93a56960 100644 --- a/project/WebDashboard/Dashboard/VelocityProjectGridAction.cs +++ b/project/WebDashboard/Dashboard/VelocityProjectGridAction.cs @@ -2,6 +2,8 @@ using System.Collections; using System.Collections.Generic; using System.Web; +//using System.Web.Http; +using System.Diagnostics; using ThoughtWorks.CruiseControl.Core; using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; using ThoughtWorks.CruiseControl.WebDashboard.IO; @@ -9,30 +11,35 @@ using ThoughtWorks.CruiseControl.WebDashboard.MVC.View; using ThoughtWorks.CruiseControl.WebDashboard.ServerConnection; using ThoughtWorks.CruiseControl.WebDashboard.Resources; +using System.Net; +using System.Collections.Specialized; +using ThoughtWorks.CruiseControl.Remote.Security; +using Microsoft.TeamFoundation.Client; +using Microsoft.TeamFoundation.Server; namespace ThoughtWorks.CruiseControl.WebDashboard.Dashboard { - // ToDo - Test! - public class VelocityProjectGridAction : IProjectGridAction - { - private readonly IFarmService farmService; - private IUrlBuilder urlBuilder; - private ICruiseUrlBuilder cruiseUrlBuilder; - private readonly IVelocityViewGenerator viewGenerator; - private readonly IProjectGrid projectGrid; - private readonly ISessionRetriever sessionRetriever; - private ProjectGridSortColumn sortColumn = ProjectGridSortColumn.Name; - private Translations translations; - - public VelocityProjectGridAction(IFarmService farmService, IVelocityViewGenerator viewGenerator, + // ToDo - Test + public class VelocityProjectGridAction : IProjectGridAction + { + private readonly IFarmService FarmService; + private IUrlBuilder UrlBuilder; + private ICruiseUrlBuilder CruiseUrlBuilder; + private readonly IVelocityViewGenerator ViewGenerator; + private readonly IProjectGrid ProjectGrid; + private readonly ISessionRetriever SessionRetriever; + private ProjectGridSortColumn SortColumn = ProjectGridSortColumn.Name; + private Translations translation; + + public VelocityProjectGridAction(IFarmService farmServices, IVelocityViewGenerator viewGenerator, IProjectGrid projectGrid, ISessionRetriever sessionRetriever) - { - this.farmService = farmService; - this.viewGenerator = viewGenerator; - this.projectGrid = projectGrid; - this.sessionRetriever = sessionRetriever; - } + { + this.FarmService = farmServices; + this.ViewGenerator = viewGenerator; + this.ProjectGrid = projectGrid; + this.SessionRetriever = sessionRetriever; + } #region Properties #region DefaultSortColumn @@ -41,8 +48,8 @@ public VelocityProjectGridAction(IFarmService farmService, IVelocityViewGenerato /// public ProjectGridSortColumn DefaultSortColumn { - get { return sortColumn; } - set { sortColumn = value; } + get { return SortColumn; } + set { SortColumn = value; } } #endregion @@ -56,63 +63,61 @@ public ProjectGridSortColumn DefaultSortColumn #endregion public IResponse Execute(string actionName, ICruiseRequest request) - { - return GenerateView(farmService.GetProjectStatusListAndCaptureExceptions(request.RetrieveSessionToken()), actionName, request, null); - } + { + return GenerateView(FarmService.GetProjectStatusListAndCaptureExceptions(request.RetrieveSessionToken()), actionName, request, null); + } public IResponse Execute(string actionName, IServerSpecifier serverSpecifier, ICruiseRequest request) - { - //Added code so since defaultServerSpecifier only sets the name of the server - not the actual config + { + //Added code so since defaultServerSpecifier only sets the name of the server - not the actual config var serverName = serverSpecifier.ServerName; - serverSpecifier = farmService.GetServerConfiguration(serverName); + serverSpecifier = FarmService.GetServerConfiguration(serverName); if (serverSpecifier == null) { throw new UnknownServerException(serverName); } else { - return GenerateView(farmService.GetProjectStatusListAndCaptureExceptions(serverSpecifier, request.RetrieveSessionToken()), actionName, request, serverSpecifier); + return GenerateView(FarmService.GetProjectStatusListAndCaptureExceptions(serverSpecifier, request.RetrieveSessionToken()), actionName, request, serverSpecifier); } - } + } - private HtmlFragmentResponse GenerateView(ProjectStatusListAndExceptions projectStatusListAndExceptions, + private HtmlFragmentResponse GenerateView(ProjectStatusListAndExceptions projectStatusListAndExceptions, string actionName, ICruiseRequest request, IServerSpecifier serverSpecifier) - { - this.translations = Translations.RetrieveCurrent(); - cruiseUrlBuilder = request.UrlBuilder; - urlBuilder = request.UrlBuilder.InnerBuilder; - Hashtable velocityContext = new Hashtable(); + { + this.translation = Translations.RetrieveCurrent(); + bool sortReverse = SortAscending(request.Request); + string category = request.Request.GetText("Category"); + CruiseUrlBuilder = request.UrlBuilder; + UrlBuilder = request.UrlBuilder.InnerBuilder; + ProjectGridSortColumn sortColumn = GetSortColumn(request.Request); + Hashtable velocityContext = new Hashtable(); velocityContext["forceBuildMessage"] = ForceBuildIfNecessary(request.Request); - velocityContext["parametersCall"] = new ServerLink(cruiseUrlBuilder, new DefaultServerSpecifier("null"), string.Empty, ProjectParametersAction.ActionName).Url; - - velocityContext["wholeFarm"] = serverSpecifier == null ? true : false; - - string category = request.Request.GetText("Category"); - velocityContext["showCategoryColumn"] = string.IsNullOrEmpty(category) ? true : false; - - ProjectGridSortColumn sortColumn = GetSortColumn(request.Request); - bool sortReverse = SortAscending(request.Request); - - velocityContext["projectNameSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.Name, sortColumn, sortReverse); - velocityContext["buildStatusSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.BuildStatus, sortColumn, sortReverse); - velocityContext["lastBuildDateSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.LastBuildDate, sortColumn, sortReverse); - velocityContext["serverNameSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.ServerName, sortColumn, sortReverse); - velocityContext["projectCategorySortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.Category, sortColumn, sortReverse); - - ProjectGridRow[] projectGridRows = projectGrid.GenerateProjectGridRows(projectStatusListAndExceptions.StatusAndServerList, actionName, sortColumn, sortReverse, category, cruiseUrlBuilder, this.translations); - + velocityContext["parametersCall"] = new ServerLink(CruiseUrlBuilder, new DefaultServerSpecifier("null"), string.Empty, ProjectParametersAction.ActionName).Url; + velocityContext["wholeFarm"] = serverSpecifier == null ? true : false; + velocityContext["showCategoryColumn"] = string.IsNullOrEmpty(category) ? true : false; + velocityContext["projectNameSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.Name, sortColumn, sortReverse); + velocityContext["buildStatusSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.BuildStatus, sortColumn, sortReverse); + velocityContext["lastBuildDateSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.LastBuildDate, sortColumn, sortReverse); + velocityContext["serverNameSortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.ServerName, sortColumn, sortReverse); + velocityContext["projectCategorySortLink"] = GenerateSortLink(serverSpecifier, actionName, ProjectGridSortColumn.Category, sortColumn, sortReverse); + velocityContext["exceptions"] = projectStatusListAndExceptions.Exceptions; + ProjectGridParameters parameters = new ProjectGridParameters(projectStatusListAndExceptions.StatusAndServerList, sortColumn, sortReverse, + category, CruiseUrlBuilder, FarmService, this.translation); + ProjectGridRow[] projectGridRows = ProjectGrid.GenerateProjectGridRows(parameters); velocityContext["projectGrid"] = projectGridRows; - velocityContext["exceptions"] = projectStatusListAndExceptions.Exceptions; Array categoryList = this.GenerateCategoryList(projectGridRows); velocityContext["categoryList"] = categoryList; + + var username = System.Security.Principal.WindowsIdentity.GetCurrent().Name.ToString(); velocityContext["barAtTop"] = (this.SuccessIndicatorBarLocation == IndicatorBarLocation.Top) || (this.SuccessIndicatorBarLocation == IndicatorBarLocation.TopAndBottom); velocityContext["barAtBottom"] = (this.SuccessIndicatorBarLocation == IndicatorBarLocation.Bottom) || (this.SuccessIndicatorBarLocation == IndicatorBarLocation.TopAndBottom); - return viewGenerator.GenerateView(@"ProjectGrid.vm", velocityContext); - } + return ViewGenerator.GenerateView(@"ProjectGrid.vm", velocityContext); + } private Array GenerateCategoryList(ProjectGridRow[] projectGridRows) { @@ -123,7 +128,7 @@ private Array GenerateCategoryList(ProjectGridRow[] projectGridRows) foreach (ProjectGridRow projectGridRow in projectGridRows) { string category = projectGridRow.Category; - System.Diagnostics.Debug.WriteLine(category); + //debug.WriteLine(category); if (!string.IsNullOrEmpty(category) && !categories.Contains(category)) categories.Add(category); @@ -137,17 +142,17 @@ private Array GenerateCategoryList(ProjectGridRow[] projectGridRows) return categories.ToArray(); } - private bool SortAscending(IRequest request) - { - return request.FindParameterStartingWith("ReverseSort") == string.Empty; - } + private bool SortAscending(IRequest request) + { + return request.FindParameterStartingWith("ReverseSort") == string.Empty; + } - private ProjectGridSortColumn GetSortColumn(IRequest request) - { - string columnName = request.GetText("SortColumn"); + private ProjectGridSortColumn GetSortColumn(IRequest request) + { + string columnName = request.GetText("SortColumn"); if (string.IsNullOrEmpty(columnName)) { - return sortColumn; + return SortColumn; } else { @@ -157,37 +162,36 @@ private ProjectGridSortColumn GetSortColumn(IRequest request) } catch (Exception) { - throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture,"Error attempting to calculate column to sort. Specified column name was [{0}]", columnName)); + throw new CruiseControlException(string.Format(System.Globalization.CultureInfo.CurrentCulture, "Error attempting to calculate column to sort. Specified column name was [{0}]", columnName)); } } - } - - private object GenerateSortLink(IServerSpecifier serverSpecifier, string action, ProjectGridSortColumn column, ProjectGridSortColumn currentColumn, bool currentReverse) - { - string queryString = "SortColumn=" + column.ToString(); - if (column == currentColumn && !currentReverse) - { - queryString += "&ReverseSort=ReverseSort"; - } - if (serverSpecifier == null) - { - return urlBuilder.BuildUrl(action, queryString); - } - else - { - return cruiseUrlBuilder.BuildServerUrl(action, serverSpecifier, queryString); - } - } - - private string ForceBuildIfNecessary(IRequest request) - { + } + + private object GenerateSortLink(IServerSpecifier serverSpecifier, string action, ProjectGridSortColumn column, ProjectGridSortColumn currentColumn, bool currentReverse) + { + string queryString = "SortColumn=" + column.ToString(); + if (column == currentColumn && !currentReverse) + { + queryString += "&ReverseSort=ReverseSort"; + } + if (serverSpecifier == null) + { + return UrlBuilder.BuildUrl(action, queryString); + } + else + { + return CruiseUrlBuilder.BuildServerUrl(action, serverSpecifier, queryString); + } + } + + private string ForceBuildIfNecessary(IRequest request) + { // Attempt to find a session token string sessionToken = request.GetText("sessionToken"); - if (string.IsNullOrEmpty(sessionToken) && (sessionRetriever != null)) + if (string.IsNullOrEmpty(sessionToken) && (SessionRetriever != null)) { - sessionToken = sessionRetriever.RetrieveSessionToken(request); + sessionToken = SessionRetriever.RetrieveSessionToken(request); } - Dictionary parameters = new Dictionary(); foreach (string parameterName in HttpContext.Current.Request.Form.AllKeys) { @@ -198,41 +202,80 @@ private string ForceBuildIfNecessary(IRequest request) } // Make the actual call - if (request.FindParameterStartingWith("StopBuild") != string.Empty) - { - farmService.Stop(ProjectSpecifier(request), sessionToken); - return this.translations.Translate("Stopping project {0}", SelectedProject(request)); - } - else if (request.FindParameterStartingWith("StartBuild") != string.Empty) - { - farmService.Start(ProjectSpecifier(request), sessionToken); - return this.translations.Translate("Starting project {0}", SelectedProject(request)); - } - else if (request.FindParameterStartingWith("ForceBuild") != string.Empty) - { - farmService.ForceBuild(ProjectSpecifier(request), sessionToken, parameters); - return this.translations.Translate("Build successfully forced for {0}", SelectedProject(request)); - } - else if (request.FindParameterStartingWith("AbortBuild") != string.Empty) - { - farmService.AbortBuild(ProjectSpecifier(request), sessionToken); - return this.translations.Translate("Abort successfully forced for {0}", SelectedProject(request)); - } - else - { - return string.Empty; - } - } - - private DefaultProjectSpecifier ProjectSpecifier(IRequest request) - { - return new DefaultProjectSpecifier( - farmService.GetServerConfiguration(request.GetText("serverName")), SelectedProject(request)); - } - - private static string SelectedProject(IRequest request) - { - return request.GetText("projectName"); - } - } + // Right now the message returned is not used, but it will in a future + if (request.FindParameterStartingWith("StopBuild") != string.Empty) + { + FarmService.Stop(ProjectSpecifier(request), sessionToken); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("Stopping project {0}", SelectedProject(request)); + } + else if (request.FindParameterStartingWith("StartBuild") != string.Empty) + { + FarmService.Start(ProjectSpecifier(request), sessionToken); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("Starting project {0}", SelectedProject(request)); + } + else if (request.FindParameterStartingWith("ForceBuild") != string.Empty) + { + FarmService.ForceBuild(ProjectSpecifier(request), sessionToken, parameters); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("Build successfully forced for {0}", SelectedProject(request)); + } + else if (request.FindParameterStartingWith("AbortBuild") != string.Empty) + { + FarmService.AbortBuild(ProjectSpecifier(request), sessionToken); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("Abort successfully forced for {0}", SelectedProject(request)); + } + else if (request.FindParameterStartingWith("CancelPending") != string.Empty) + { + FarmService.CancelPendingRequest(ProjectSpecifier(request), sessionToken); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("Cancel pending successfully forced for {0}", SelectedProject(request)); + } + else if (request.FindParameterStartingWith("Volunteer") != string.Empty) + { + string userName = request.GetText("FixerName"); + if (userName != string.Empty) + { + return SendFixerMessage(userName, request, sessionToken); + } + else + { + return this.translation.Translate("Fixer's name cannot be empty"); + } + } + else + { + return string.Empty; + } + } + + private DefaultProjectSpecifier ProjectSpecifier(IRequest request) + { + return new DefaultProjectSpecifier( + FarmService.GetServerConfiguration(request.GetText("serverName")), SelectedProject(request)); + } + + private static string SelectedProject(IRequest request) + { + return request.GetText("projectName"); + } + + private string SendFixerMessage(string userName, IRequest request, string sessionToken) + { + if (userName.Equals("nobody", StringComparison.InvariantCultureIgnoreCase)) + { + FarmService.RemoveFixer(ProjectSpecifier(request), sessionToken); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("{0} removed as fixer for {1}", userName, SelectedProject(request)); + } + else + { + FarmService.VolunteerFixer(ProjectSpecifier(request), sessionToken, userName); + System.Web.HttpContext.Current.Response.Redirect(request.RawUrl, false); + return this.translation.Translate("{0} succesfully selected as a fixer for {1}", userName, SelectedProject(request)); + } + } + } } diff --git a/project/WebDashboard/Plugins/FarmReport/CategorizedFarmReportFarmPlugin.cs b/project/WebDashboard/Plugins/FarmReport/CategorizedFarmReportFarmPlugin.cs index 9fc72c586..84ff886c7 100644 --- a/project/WebDashboard/Plugins/FarmReport/CategorizedFarmReportFarmPlugin.cs +++ b/project/WebDashboard/Plugins/FarmReport/CategorizedFarmReportFarmPlugin.cs @@ -1,4 +1,4 @@ -namespace ThoughtWorks.CruiseControl.WebDashboard.Plugins.FarmReport +namespace ThoughtWorks.CruiseControl.WebDashboard.Plugins.FarmReport { using System.Collections; using System.Collections.Generic; @@ -17,6 +17,7 @@ using ThoughtWorks.CruiseControl.Core; using System.Web; using System.Linq; + using System.Diagnostics; [ReflectorType("categorizedFarmReportFarmPlugin")] @@ -72,13 +73,21 @@ public IResponse Execute(ICruiseRequest request) var sessionToken = request.RetrieveSessionToken(); velocityContext["forceBuildMessage"] = ForceBuildIfNecessary(request.Request, sessionToken); - var gridRows = this.projectGrid.GenerateProjectGridRows(projectStatus.StatusAndServerList, BaseActionName, - ProjectGridSortColumn.Category, true, - category, urlBuilder, this.translations); + ProjectGridParameters parameters = + new ProjectGridParameters( + projectStatus.StatusAndServerList, + ProjectGridSortColumn.Category, + true, + BaseActionName, + urlBuilder, + farmService, + this.translations); + + var gridRows = this.projectGrid.GenerateProjectGridRows(parameters); var categories = new SortedDictionary(); - foreach (var row in gridRows.OrderBy( s=> s.ServerName).ThenBy( p => p.Name)) + foreach (var row in gridRows.OrderBy(s => s.ServerName).ThenBy(p => p.Name)) { var rowCategory = row.Category; CategoryInformation categoryRows; @@ -95,7 +104,7 @@ public IResponse Execute(ICruiseRequest request) // it's annoying to specify a category and still have to press the show link if (!string.IsNullOrEmpty(category)) { - categories[category].Display = true; + categories[category].Display = true; } @@ -167,6 +176,11 @@ private string ForceBuildIfNecessary(IRequest request, string sessionToken) farmService.AbortBuild(ProjectSpecifier(request), sessionToken); return this.translations.Translate("Abort successfully forced for {0}", SelectedProject(request)); } + else if (request.FindParameterStartingWith("CancelPending") != string.Empty) + { + farmService.CancelPendingRequest(ProjectSpecifier(request), sessionToken); + return this.translations.Translate("Cancel pending successfully forced for {0}", SelectedProject(request)); + } else { return string.Empty; diff --git a/project/WebDashboard/ServerConnection/IFarmService.cs b/project/WebDashboard/ServerConnection/IFarmService.cs index f9a3ba9ec..02bae1a7f 100644 --- a/project/WebDashboard/ServerConnection/IFarmService.cs +++ b/project/WebDashboard/ServerConnection/IFarmService.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using ThoughtWorks.CruiseControl.Core.Reporting.Dashboard.Navigation; using ThoughtWorks.CruiseControl.Remote; using ThoughtWorks.CruiseControl.Remote.Parameters; @@ -7,8 +7,8 @@ namespace ThoughtWorks.CruiseControl.WebDashboard.ServerConnection { - public interface IFarmService - { + public interface IFarmService + { IBuildSpecifier[] GetMostRecentBuildSpecifiers(IProjectSpecifier projectSpecifier, int buildCount, string sessionToken); IBuildSpecifier[] GetBuildSpecifiers(IProjectSpecifier serverSpecifier, string sessionToken); void DeleteProject(IProjectSpecifier projectSpecifier, bool purgeWorkingDirectory, bool purgeArtifactDirectory, bool purgeSourceControlEnvironment, string sessionToken); @@ -18,13 +18,16 @@ public interface IFarmService void AbortBuild(IProjectSpecifier projectSpecifier, string sessionToken); void Start(IProjectSpecifier projectSpecifier, string sessionToken); void Stop(IProjectSpecifier projectSpecifier, string sessionToken); + void CancelPendingRequest(IProjectSpecifier projectSpecifier, string sessionToken); void ForceBuild(IProjectSpecifier projectSpecifier, string sessionToken, Dictionary parameters); - ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(string sessionToken); + void VolunteerFixer(IProjectSpecifier projectSpecifier, string sessionToken, string fixingUserName); + void RemoveFixer(IProjectSpecifier projectSpecifier, string sessionToken); + ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(string sessionToken); ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(IServerSpecifier serverSpecifier, string sessionToken); ExternalLink[] GetExternalLinks(IProjectSpecifier projectSpecifier, string sessionToken); - IServerSpecifier[] GetServerSpecifiers(); + IServerSpecifier[] GetServerSpecifiers(); IServerSpecifier GetServerConfiguration(string serverName); - string GetServerVersion(IServerSpecifier serverSpecifier, string sessionToken); + string GetServerVersion(IServerSpecifier serverSpecifier, string sessionToken); string GetArtifactDirectory(IProjectSpecifier projectSpecifier, string sessionToken); string GetStatisticsDocument(IProjectSpecifier projectSpecifier, string sessionToken); CruiseServerSnapshotListAndExceptions GetCruiseServerSnapshotListAndExceptions(string sessionToken); @@ -91,8 +94,8 @@ public interface IFarmService /// /// A list of s containing the audit details. List ReadAuditRecords(IServerSpecifier serverSpecifier, string sessionToken, int startPosition, int numberOfRecords); - - /// + + /// /// Reads the specified number of filtered audit events. /// /// The starting position. diff --git a/project/WebDashboard/ServerConnection/ServerAggregatingCruiseManagerWrapper.cs b/project/WebDashboard/ServerConnection/ServerAggregatingCruiseManagerWrapper.cs index 31f50d890..2942c7465 100644 --- a/project/WebDashboard/ServerConnection/ServerAggregatingCruiseManagerWrapper.cs +++ b/project/WebDashboard/ServerConnection/ServerAggregatingCruiseManagerWrapper.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net.Sockets; using ThoughtWorks.CruiseControl.Core; @@ -9,25 +9,27 @@ using ThoughtWorks.CruiseControl.Remote.Parameters; using ThoughtWorks.CruiseControl.Remote.Security; using ThoughtWorks.CruiseControl.WebDashboard.Configuration; +using ThoughtWorks.CruiseControl.CCTrayLib.Presentation; +using ThoughtWorks.CruiseControl.CCTrayLib.Monitoring; namespace ThoughtWorks.CruiseControl.WebDashboard.ServerConnection { public class ServerAggregatingCruiseManagerWrapper : ICruiseManagerWrapper, IFarmService - { + { private readonly ICruiseServerClientFactory clientFactory; - private readonly IRemoteServicesConfiguration configuration; + private readonly IRemoteServicesConfiguration configuration; public ServerAggregatingCruiseManagerWrapper(IRemoteServicesConfiguration configuration, ICruiseServerClientFactory managerFactory) - { - this.configuration = configuration; - this.clientFactory = managerFactory; - } + { + this.configuration = configuration; + this.clientFactory = managerFactory; + } public IBuildSpecifier GetLatestBuildSpecifier(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) .GetLatestBuildName(projectSpecifier.ProjectName); - return new DefaultBuildSpecifier(projectSpecifier, response); + return new DefaultBuildSpecifier(projectSpecifier, response); } #region GetLog() @@ -65,39 +67,39 @@ public string GetLog(IBuildSpecifier buildSpecifier, string sessionToken) #endregion public IBuildSpecifier[] GetBuildSpecifiers(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) .GetBuildNames(projectSpecifier.ProjectName); return CreateBuildSpecifiers(projectSpecifier, response); - } + } public IBuildSpecifier[] GetMostRecentBuildSpecifiers(IProjectSpecifier projectSpecifier, int buildCount, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier, sessionToken) .GetMostRecentBuildNames(projectSpecifier.ProjectName, buildCount); return CreateBuildSpecifiers(projectSpecifier, response); - } - - private IBuildSpecifier[] CreateBuildSpecifiers(IProjectSpecifier projectSpecifier, string[] buildNames) - { - var buildSpecifiers = new List(); - foreach (string buildName in buildNames) - { - buildSpecifiers.Add(new DefaultBuildSpecifier(projectSpecifier, buildName)); - } - return buildSpecifiers.ToArray(); - } + } + + private IBuildSpecifier[] CreateBuildSpecifiers(IProjectSpecifier projectSpecifier, string[] buildNames) + { + var buildSpecifiers = new List(); + foreach (string buildName in buildNames) + { + buildSpecifiers.Add(new DefaultBuildSpecifier(projectSpecifier, buildName)); + } + return buildSpecifiers.ToArray(); + } public void DeleteProject(IProjectSpecifier projectSpecifier, bool purgeWorkingDirectory, bool purgeArtifactDirectory, bool purgeSourceControlEnvironment, string sessionToken) - { + { GetCruiseManager(projectSpecifier, sessionToken) .DeleteProject(projectSpecifier.ProjectName, purgeWorkingDirectory, purgeArtifactDirectory, purgeSourceControlEnvironment); - } + } public void ForceBuild(IProjectSpecifier projectSpecifier, string sessionToken) { ForceBuild(projectSpecifier, sessionToken, new Dictionary()); - } + } public void ForceBuild(IProjectSpecifier projectSpecifier, string sessionToken, Dictionary parameters) { @@ -106,9 +108,26 @@ public void ForceBuild(IProjectSpecifier projectSpecifier, string sessionToken, } public void AbortBuild(IProjectSpecifier projectSpecifier, string sessionToken) - { + { GetCruiseManager(projectSpecifier, sessionToken).AbortBuild(projectSpecifier.ProjectName); - } + } + + public void CancelPendingRequest(IProjectSpecifier projectSpecifier, string sessionToken) + { + GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) + .CancelPendingRequest(projectSpecifier.ProjectName); + } + + public void VolunteerFixer(IProjectSpecifier projectSpecifier, string sessionToken, string fixingUserName) + { + string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, "Fixer : {0}.", fixingUserName); + GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken).SendMessage(projectSpecifier.ProjectName, new Message(message, Message.MessageKind.Fixer)); + } + + public void RemoveFixer(IProjectSpecifier projectSpecifier, string sessionToken) + { + GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken).SendMessage(projectSpecifier.ProjectName, new Message(string.Empty, Message.MessageKind.Fixer)); + } private ServerLocation GetServerUrl(IServerSpecifier serverSpecifier) { @@ -131,15 +150,15 @@ public ExternalLink[] GetExternalLinks(IProjectSpecifier projectSpecifier, strin return response; } - public ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(string sessionToken) + public ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(string sessionToken) { - return GetProjectStatusListAndCaptureExceptions(GetServerSpecifiers(), sessionToken); + return GetProjectStatusListAndCaptureExceptions(GetServerSpecifiers(), sessionToken); } public ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(IServerSpecifier serverSpecifier, string sessionToken) - { - return GetProjectStatusListAndCaptureExceptions(new[] {serverSpecifier}, sessionToken); - } + { + return GetProjectStatusListAndCaptureExceptions(new[] { serverSpecifier }, sessionToken); + } private ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions(IServerSpecifier[] serverSpecifiers, string sessionToken) { @@ -170,85 +189,85 @@ private ProjectStatusListAndExceptions GetProjectStatusListAndCaptureExceptions( } private void AddException(List exceptions, IServerSpecifier serverSpecifier, Exception e) - { - exceptions.Add(new CruiseServerException(serverSpecifier.ServerName, GetServerUrl(serverSpecifier).Url, e)); - } + { + exceptions.Add(new CruiseServerException(serverSpecifier.ServerName, GetServerUrl(serverSpecifier).Url, e)); + } public string GetServerLog(IServerSpecifier serverSpecifier, string sessionToken) - { + { var response = GetCruiseManager(serverSpecifier, sessionToken) .GetServerLog(); return response; - } + } public string GetServerLog(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) .GetServerLog(projectSpecifier.ProjectName); return response; - } + } public void Start(IProjectSpecifier projectSpecifier, string sessionToken) - { + { GetCruiseManager(projectSpecifier, sessionToken) .StartProject(projectSpecifier.ProjectName); - } + } public void Stop(IProjectSpecifier projectSpecifier, string sessionToken) - { + { GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) .StopProject(projectSpecifier.ProjectName); - } + } - public string GetServerVersion(IServerSpecifier serverSpecifier, string sessionToken) - { + public string GetServerVersion(IServerSpecifier serverSpecifier, string sessionToken) + { var response = GetCruiseManager(serverSpecifier, sessionToken) .GetServerVersion(); return response; - } - - public IServerSpecifier[] GetServerSpecifiers() - { - var serverSpecifiers = new List(); - foreach (ServerLocation serverLocation in ServerLocations) - { - serverSpecifiers.Add(new DefaultServerSpecifier(serverLocation.Name, serverLocation.AllowForceBuild, serverLocation.AllowStartStopBuild)); - } - return serverSpecifiers.ToArray(); - } + } + + public IServerSpecifier[] GetServerSpecifiers() + { + var serverSpecifiers = new List(); + foreach (ServerLocation serverLocation in ServerLocations) + { + serverSpecifiers.Add(new DefaultServerSpecifier(serverLocation.Name, serverLocation.AllowForceBuild, serverLocation.AllowStartStopBuild)); + } + return serverSpecifiers.ToArray(); + } public void AddProject(IServerSpecifier serverSpecifier, string serializedProject, string sessionToken) - { + { GetCruiseManager(serverSpecifier, sessionToken).AddProject(serializedProject); - } + } public string GetProject(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken) .GetProject(projectSpecifier.ProjectName); return response; - } + } public void UpdateProject(IProjectSpecifier projectSpecifier, string serializedProject, string sessionToken) - { + { GetCruiseManager(projectSpecifier, sessionToken) .UpdateProject(projectSpecifier.ProjectName, serializedProject); - } + } public string GetArtifactDirectory(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier, sessionToken) .GetArtifactDirectory(projectSpecifier.ProjectName); return response; - } + } public string GetStatisticsDocument(IProjectSpecifier projectSpecifier, string sessionToken) - { + { var response = GetCruiseManager(projectSpecifier, sessionToken) .GetStatisticsDocument(projectSpecifier.ProjectName); return response; - } + } public string GetModificationHistoryDocument(IProjectSpecifier projectSpecifier, string sessionToken) { @@ -265,17 +284,17 @@ public string GetRSSFeed(IProjectSpecifier projectSpecifier, string sessionToken } private CruiseServerClientBase GetCruiseManager(IBuildSpecifier buildSpecifier, string sessionToken) - { - return GetCruiseManager(buildSpecifier.ProjectSpecifier.ServerSpecifier, sessionToken); - } + { + return GetCruiseManager(buildSpecifier.ProjectSpecifier.ServerSpecifier, sessionToken); + } private CruiseServerClientBase GetCruiseManager(IProjectSpecifier projectSpecifier, string sessionToken) - { + { return GetCruiseManager(projectSpecifier.ServerSpecifier, sessionToken); - } + } private CruiseServerClientBase GetCruiseManager(IServerSpecifier serverSpecifier, string sessionToken) - { + { var config = GetServerUrl(serverSpecifier); CruiseServerClientBase manager = clientFactory.GenerateClient(config.Url, new ClientStartUpSettings @@ -284,11 +303,11 @@ private CruiseServerClientBase GetCruiseManager(IServerSpecifier serverSpecifier }); manager.SessionToken = sessionToken; return manager; - } + } - private ServerLocation[] ServerLocations + private ServerLocation[] ServerLocations { - get { return configuration.Servers; } + get { return configuration.Servers; } } public IServerSpecifier GetServerConfiguration(string serverName) @@ -312,16 +331,16 @@ public CruiseServerSnapshotListAndExceptions GetCruiseServerSnapshotListAndExcep } public string Login(string server, LoginRequest credentials) - { + { var manager = GetCruiseManager(GetServerConfiguration(server), null); manager.Login(credentials.Credentials); return manager.SessionToken; - } + } public void Logout(string server, string sessionToken) - { + { GetCruiseManager(GetServerConfiguration(server), sessionToken).Logout(); - } + } public string GetDisplayName(string server, string sessionToken) { @@ -454,7 +473,7 @@ public virtual List ListBuildParameters(IProjectSpecifier project return GetCruiseManager(projectSpecifier, sessionToken) .ListBuildParameters(projectSpecifier.ProjectName); } - + /// /// Reads all the specified number of audit events. /// diff --git a/project/WebDashboard/Web.config b/project/WebDashboard/Web.config index 7b86acfbe..1caea0f38 100644 --- a/project/WebDashboard/Web.config +++ b/project/WebDashboard/Web.config @@ -5,6 +5,9 @@ + + + + -
+ + -
+ + align="right" + name="Refresh" + value="$translations.Translate('Refresh status')" + class="refreshStatus" + />
-#if ($forceBuildMessage.Length > 0) -

- - - $translations.Translate($forceBuildMessage) - - -

-#end - #set ($ProjectOKCounter = 0) #set ($ProjectNOKCounter = 0) #foreach ($projectGridRow in $projectGrid) - #if ($projectGridRow.BuildStatus == "Success") - #set ($ProjectOKCounter = $ProjectOKCounter + 1) - #else - #set ($ProjectNOKCounter = $ProjectNOKCounter + 1) - #end +#set($ProjectServer = $projectGridRow.ServerName) +#if ($projectGridRow.BuildStatus == "Success") +#set ($ProjectOKCounter = $ProjectOKCounter + 1) +#else +#set ($ProjectNOKCounter = $ProjectNOKCounter + 1) +#end #end #set ($ProjectCounter = $ProjectOKCounter + $ProjectNOKCounter) #if ($ProjectCounter == 0) - #set ($OKPercent = 50) - #set ($NOKPercent = 0) +#set ($OKPercent = 50) +#set ($NOKPercent = 0) #else - #set ($OKPercent = 50 * $ProjectOKCounter / $ProjectCounter) - #set ($NOKPercent = 50 - $OKPercent) +#set ($OKPercent = 50 * $ProjectOKCounter / $ProjectCounter) +#set ($NOKPercent = 50 - $OKPercent) #end #set ($OKPercentToolTip = $OKPercent * 2) +
+

Caption [

+ + Start | + + Stop | + + Abort | + + Force run | + + Cancel Pending

]

+
+ +#if ($forceBuildMessage.Length > 0) +

+ + + $translations.Translate($forceBuildMessage) + + +

+#end + #if ($projectGrid.Length > 0) - - - #if ($barAtTop) - - + + + #end +
- - - #if ($OKPercent == 50) - + #end - - - - - - - - - - - - - #set ($RowId = 0) - #foreach ($projectGridRow in $projectGrid) - #set ($RowId = $RowId + 1) + + + + + + + + + + + + + + + #set ($RowId = 0) + #foreach ($projectGridRow in $projectGrid) + #set ($RowId = $RowId + 1) + #set($colorText="") + #set($cont=0) + + #if ($projectGridRow.BuildStatus == "Failure" ) + #set($colorText = "Red") + #elseif ($projectGridRow.BuildStatus == "Exception" ) + #set($colorText = "Orange") + #elseif ($projectGridRow.BuildStatus == "Unknown" ) + #set($colorText = "Blue") + #elseif ($projectGridRow.BuildStatus == "Success" ) + #set($colorText = "Green") + #end + + + + + #if ($projectGridRow.Breakers.Length == 0) + - #if ($wholeFarm) - + + + + #foreach($userName in $projectGridRow.BreakersNames) + + + + + + #end + #if($projectGridRow.ForceBuildPublisher.Length > 0 && $projectGridRow.Breakers.Length == 0) +
  • $projectGridRow.ForceBuildPublisher
  • + #elseif($projectGridRow.ForceBuildPublisher.Length > 0) +
  • $projectGridRow.ForceBuildPublisher
  • #end - - - - - - - - - + + + + + + - #if ($projectGridRow.BuildStage.Length > 0) - - #if ($wholeFarm) - - #else - - #end - + #if ($projectGridRow.BuildStage.Length > 0) + + #if ($wholeFarm) + + #else + #end + + #end #end - #if ($barAtBottom) - - - +
    + + + #if ($barAtTop) + + - - #end - - #if ($wholeFarm) - + #end + +
    + + + #if ($OKPercent == 50) + - #else - - - - - #end - -
    -
    $translations.Translate("Server")
    +
    $translations.Translate("Admin")$translations.Translate("Project Name")$translations.Translate("Last Build Status")$translations.Translate("Last Build Time")$translations.Translate("Next Build Time")$translations.Translate("Last Build Label")$translations.Translate("CCNet Status")$translations.Translate("Activity")$translations.Translate("Messages")
    $translations.Translate("Project Name")$translations.Translate("Last Build")$translations.Translate("Statistics")$translations.Translate("Messages")$translations.Translate("Last Build Time")$translations.Translate("Run Time")$translations.Translate("Status")$translations.Translate("Activity")$translations.Translate("Admin")
    + $projectGridRow.Name + + #if($projectGridRow.BuildStatus == "Failure") + $projectGridRow.Statistics + #else + + #end + #if($projectGridRow.BuildStatus == "Failure") + #if(!($projectGridRow.Fixer.Length > 0)) +
    + + -
    $projectGridRow.ServerName -
    + #if ($projectGridRow.Fixer.Length > 0) + #if($projectGridRow.Breakers.Length > 0) + + #else + + #end +
  • $projectGridRow.Fixer
  • + name="projectName" + value="$projectGridRow.Name" /> - - #if ($projectGridRow.allowForceBuild) - #if($projectGridRow.ForceAbortBuildButtonValue == "Force") - - #else - - #end - #end - #if ($projectGridRow.AllowStartStopBuild) - - #end - + name="serverName" + value="$projectGridRow.ServerName" /> + + + +
    -
    - $projectGridRow.Name - $translations.Translate($projectGridRow.BuildStatus)$projectGridRow.LastBuildDate$translations.Translate($projectGridRow.NextBuildTime)$translations.Translate($projectGridRow.LastBuildLabel)$translations.Translate($projectGridRow.Status)$translations.Translate($projectGridRow.Activity.ToString()) + #end + #if ($projectGridRow.Breakers.Length > 0)
      - #if ($projectGridRow.Breakers.Length > 0) -
    • $translations.Translate("Breakers : {0}", $projectGridRow.Breakers)
    • - #end - #if ($projectGridRow.Fixer.Length > 0) -
    • $projectGridRow.Fixer
    • - #end - #if ($projectGridRow.FailingTasks.Length > 0) -
    • $translations.Translate("Failing Tasks : {0}", $projectGridRow.FailingTasks)
    • - #end +
    • + $translations.Translate("Breakers :
      {0}",$projectGridRow.Breakers) +
    + #end + #end
    + $projectGridRow.LastBuildDate + + + $projectGridRow.RunningTime + + $translations.Translate($projectGridRow.Status) + + #if($projectGridRow.Activity.ToString() == "Pending") + + #else + + #end + $translations.Translate($projectGridRow.Activity.ToString()) (P$projectGridRow.QueuePriority) + #if($projectGridRow.Activity.ToString() == "Pending") + #if($projectGridRow.QueuePosition < 10) + (Q0$projectGridRow.QueuePosition) + #else + (Q$projectGridRow.QueuePosition) + #end + #end + + +
    + + + + + #if ($projectGridRow.allowForceBuild) + #if($projectGridRow.ForceAbortBuildButtonValue == "Force") + #if($projectGridRow.Activity == "Pending") + + + + #else + + #if($projectGridRow.BuildParametersCount > 0) + + #else + + #end + + #end + #else + + + + #end + #end + + #if($projectGridRow.Activity.ToString() == "Pending") + + #else + + #end + + #if ($projectGridRow.AllowStartStopBuild) + #if ($projectGridRow.Status == "Running") + + + + #else + + + + #end + #end + +
    +
    $translations.FormatBuildStage($projectGridRow.BuildStage)$translations.FormatBuildStage($projectGridRow.BuildStage)
    $translations.FormatBuildStage($projectGridRow.BuildStage)$translations.FormatBuildStage($projectGridRow.BuildStage)
    - - - #if ($OKPercent == 50) - + - - - #end -
    +
    + + + #if ($OKPercent == 50) + - #else - - - - - #end - -
    -
    + #end +
    +
    + #end - - - #if ($exceptions.Length > 0)

    - $translations.Translate("There were exceptions connecting to the following servers"): + $translations.Translate("There were exceptions connecting to the following servers"):

    + cellpadding="4" + rules="all" + bordercolor="#CC9966" + border="1" + id="ExceptionGrid" + bgcolor="White" + width="100%">
    diff --git a/project/core/Project.cs b/project/core/Project.cs index 03b3b719d..adf434e23 100644 --- a/project/core/Project.cs +++ b/project/core/Project.cs @@ -117,7 +117,7 @@ public class Project : ProjectBase, IProject, IIntegrationRunnerTarget, IIntegra private IConfiguration configuration; private IExecutionEnvironment currentExecutionEnvironment; private bool writeSummaryFile; - + #region Constructors /// /// Initializes a new instance of the class. @@ -269,8 +269,8 @@ public int MaxSourceControlRetries /// 1.4 /// false [ReflectorProperty("stopProjectOnReachingMaxSourceControlRetries", Required = false)] - public bool StopProjectOnReachingMaxSourceControlRetries {get; set;} - + public bool StopProjectOnReachingMaxSourceControlRetries { get; set; } + /// /// (Should) show or hide the ForceBuildButton in UI programs. This is an extra setting on top of security. /// This is setting is mainly meant to disable the possibility to force a project via a UI. (dashboard and cctray) @@ -281,8 +281,8 @@ public int MaxSourceControlRetries /// 1.6 /// True [ReflectorProperty("showForceBuildButton", Required = false)] - public bool ShowForceBuildButton {get; set;} - + public bool ShowForceBuildButton { get; set; } + /// /// (Should) show or hide the Start - Stop Button in UI programs. This is an extra setting on top of security. @@ -295,7 +295,7 @@ public int MaxSourceControlRetries /// True [ReflectorProperty("showStartStopButton", Required = false)] public bool ShowStartStopButton { get; set; } - + /// /// What action to take when a source control error occurs (during GetModifications). @@ -555,9 +555,9 @@ public IIntegrationResult Integrate(IntegrationRequest request) var timer = new Stopwatch(); timer.Start(); var summary = new BuildSummary - { - StartTime = DateTime.Now - }; + { + StartTime = DateTime.Now + }; var logDirectory = this.GetLogDirectory(); var fileSystem = new SystemIoFileSystem(); var serialiser = new XmlSerializer(typeof(BuildSummary)); @@ -662,13 +662,13 @@ public IList GetSummaries(int start, int count) var fileSystem = new SystemIoFileSystem(); var serialiser = new XmlSerializer(typeof(BuildSummary)); Func loadSummary = f => - { - using (var stream = fileSystem.OpenInputStream(f)) - { - var summary = serialiser.Deserialize(stream); - return summary as BuildSummary; - } - }; + { + using (var stream = fileSystem.OpenInputStream(f)) + { + var summary = serialiser.Deserialize(stream); + return summary as BuildSummary; + } + }; var files = fileSystem.GetFilesInDirectory(logDirectory, "*.summary", SearchOption.TopDirectoryOnly); summaries.AddRange( files.OrderByDescending(f => f).Skip(start).Take(count).Select(loadSummary)); @@ -1066,6 +1066,10 @@ private void RunTask(ITask task, IIntegrationResult result, bool isPublisher) if (baseTask != null) { wasSuccessful = baseTask.WasSuccessful; + if (!wasSuccessful) + { + DetectWhatPublisherFailed(baseTask.Name); + } } // Only need to update the status if it is not already set @@ -1098,6 +1102,27 @@ private void RunTask(ITask task, IIntegrationResult result, bool isPublisher) } } + private void DetectWhatPublisherFailed(string taskName) + { + switch (taskName) + { + case "ForceBuildPublisher": + messages.Add(new Message("ForceBuildPublisher Failed", Message.MessageKind.ForceBuildPublisherFailed)); + break; + case "PowerShellTask": + messages.Add(new Message("PowerShellTask Failed", Message.MessageKind.ForceBuildPublisherFailed)); + break; + case "XmlLogPublisher": + messages.Add(new Message("XmlLogPublisher Failed", Message.MessageKind.ForceBuildPublisherFailed)); + break; + case "StatisticsPublisher": + messages.Add(new Message("StatisticsPublisher Failed", Message.MessageKind.ForceBuildPublisherFailed)); + break; + case "ArtifactCleanUpTask": + messages.Add(new Message("ArtifactCleanUp Task Failed", Message.MessageKind.ForceBuildPublisherFailed)); + break; + } + } /// /// Cancels any tasks that have not been run. /// @@ -1896,4 +1921,4 @@ public void InitialiseForBuild(IntegrationRequest request) this.AddMessage(new Message(request.ToString(), Message.MessageKind.BuildStatus)); } } -} \ No newline at end of file +}