This class is responsible for generating a complete XML status report on a site.
        public void GetConfiguration_NullArrayOutputs_All()
        {
            CreateNeccessaryDir();

            var component = new Component()
                    {
                        Name = "site-status.Test",
                        Version = "0.1.123"
                    };

            WriteFiles(component);

            var target = new SiteStatusRepository("");

            var report = target.GetConfiguration();
            var reportProperties = report.GetType();
            var reportArrayPropertyGets = (
                from prop in report.GetType().GetProperties()
                where
                    prop.PropertyType.IsArray
                    && prop.GetGetMethod() != null
                select prop.GetGetMethod()
            ).ToList();

            foreach(var get in reportArrayPropertyGets)
            {
                Assert.IsNull(get.Invoke(report, null));
            }
        }
            /// <summary>
            /// Checks to see if there was an error during the retrieval of the 
            /// version files from the <c>VersionDirectory</c>.
            /// </summary>
            /// <param name="issue">The issue object to contain information 
            /// about the exception.</param>
            /// <param name="repo">The SiteStatusRepository object that this 
            /// issue occurred in.</param>
            /// <returns>Whether or not this was the cause of the issue.</returns>
            private static bool CheckForGetFilesIssue(SiteStatusIssue issue, SiteStatusRepository repo)
            {
                bool result = false;
                try
                {
                    repo.VersionDirectory.GetFiles(VERSION_FILE_MASK);
                }
                catch (ArgumentNullException)
                {
                    result = true;
                    issue.ProbableCause = "The mask to search for version files in the version directory is null.";
                }
                catch(ArgumentException)
                {
                    result = true;
                    issue.ProbableCause = "The mask to search for version files in the version directory contains invalid characters.";
                }
                catch (DirectoryNotFoundException)
                {
                    result = true;
                    issue.ProbableCause = "The mask specified to search for version files in the version directory is invalid, such as being on an unmapped drive.";

                }
                catch (SecurityException)
                {
                    result = true;
                    issue.ProbableCause = "The mask specified to search for version files in the version directory could not be used due to insufficient permissions.";
                }
                catch(Exception)
                {

                }

                return result;
            }
            /// <summary>
            /// Must be run after the other VersionDirectory checks.
            /// </summary>
            /// <param name="issue">The issue object to contain information 
            /// about the exception.</param>
            /// <param name="repo">The SiteStatusRepository object that this 
            /// issue occurred in.</param>
            /// <returns>Whether or not it was an exception thrown by the 
            /// constructor of DirectoryInfo or not.</returns>
            private static bool CheckForDirectoryInfoIssue(SiteStatusIssue issue, SiteStatusRepository repo)
            {
                bool result = false;
                try
                {
                    var versionDir = repo.VersionDirectory;
                }
                catch(ArgumentNullException)
                {
                    result = true;
                    issue.ProbableCause = "The version directory path is null.";
                }
                catch(SecurityException)
                {
                    result = true;
                    issue.ProbableCause = "The version directory may not be accessed due to insufficient permissions.";
                }
                catch(ArgumentException)
                {
                    result = true;
                    issue.ProbableCause = "The version directory contains invalid characters.";
                }
                catch(PathTooLongException)
                {
                    result = true;
                    issue.ProbableCause = "The version directory path is too long.";
                }
                catch (Exception)
                {

                }

                return result;
            }
            public static SiteStatusIssue Get(SiteStatusRepository repo, Exception ex)
            {
                var siteStatusIssue = new SiteStatusIssue()
                {
                    FailedTaskDescription = "The directory with the version files could not be read.",
                    Implications = "The versions for the various components in the site will not be reported.",
                    Exception = ex
                };

                if (CheckForConfigFileError(siteStatusIssue))
                {

                }
                else if(CheckForMissingAppSetting(siteStatusIssue))
                {

                }
                else if (CheckForDirectoryInfoIssue(siteStatusIssue, repo))
                {

                }
                else if(CheckForGetFilesIssue(siteStatusIssue, repo))
                {

                }
                else
                {
                    siteStatusIssue.ProbableCause = "Unknown";
                }

                return siteStatusIssue;
            }
        public void GetServices_Database_Unknown()
        {
            CreateNeccessaryDir();

            var component = new Component()
            {
                Name = "site-status.Test",
                Version = "0.1.123"
            };

            List<Service> services = new List<Service>()
            {
                new Service
                {
                    Name = "NoDbConnectionMonitor",
                    Type = ServiceType.Database
                }
            };

            WriteFiles(component, services);

            var target = new SiteStatusRepository("");

            var actualServices = target.GetServices();
            Assert.IsNotNull(actualServices);
            Assert.AreEqual(1, actualServices.Count);
            Assert.AreEqual(actualServices[0].Status, ServiceStatus.Unknown);
        }
        public void WriteErrors_StatusConfigurationFormatProblem()
        {
            CreateNeccessaryDir();

            var statusConfigContents = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
                + "<Report xmlns=\"com.iinteractive.reporting\">"
                // The quotations after Type="Service is missing.
                + "<Service Name=\"SomeServiceName\" Type=\"Service />"
                + "</Report>";

            var component = new Component()
            {
                Name = "site-status.Test",
                Version = "0.1.123"
            };

            #region PREPARES FOR THE TEST
            var statusConfig = new Report();

            using (var writer = new StreamWriter(Path.Combine(SiteStatusDirectory, "Site.ver")))
            {
                component.SerializeTo(writer);
            }

            using (var writer = new StreamWriter(ConfigurationPath))
            {
                writer.Write(statusConfigContents);
            }
            #endregion

            var target = new SiteStatusRepository("");
            var result = "";
            using(var writer = new StringWriter())
            {
                target.WriteErrors(writer);
                result = writer.ToString();
            }

            var serializer = new XmlSerializer(typeof(List<SiteStatusIssue>), new Type[] { typeof(SiteStatusIssue) });
            using(var reader = new StringReader(result))
            {
                var actualErrors = (List<SiteStatusIssue>)serializer.Deserialize(reader);
                Assert.IsNotNull(actualErrors);
                Assert.AreNotEqual(0, actualErrors.Count);
            }
        }
        public void WriteErrors_StatusConfigurationDoesNotExistError()
        {
            DeleteDir();

            CreateNeccessaryDir();

            var component = new Component()
            {
                Name = "site-status.Test",
                Version = "0.1.123"
            };

            List<Service> services = new List<Service>()
            {
                new Service
                {
                    Name = "NoDbConnectionMonitor",
                    Type = ServiceType.Database
                }
            };

            #region PREPARES FOR THE TEST
            var statusConfig = new Report();
            if (services == null)
                services = new List<Service>();

            statusConfig.Service = services.ToArray();

            using (var writer = new StreamWriter(Path.Combine(SiteStatusDirectory, "Site.ver")))
            {
                component.SerializeTo(writer);
            }
            #endregion

            var target = new SiteStatusRepository("");
            var result = "";
            using (var writer = new StringWriter())
            {
                target.WriteErrors(writer);
                result = writer.ToString();
            }

            var serializer = new XmlSerializer(typeof(List<SiteStatusIssue>), new Type[] { typeof(SiteStatusIssue) });
            using (var reader = new StringReader(result))
            {
                var actualErrors = (List<SiteStatusIssue>)serializer.Deserialize(reader);
                Assert.IsNotNull(actualErrors);
                Assert.AreNotEqual(0, actualErrors.Count);
            }
        }
        public void WriteErrors_NoErrors_All()
        {
            DeleteDir();

            CreateNeccessaryDir();

            var component = new Component()
            {
                Name = "site-status.Test",
                Version = "0.1.123"
            };

            List<Service> services = new List<Service>()
            {
                // We give it a bad connection, because it shouldn't be
                // reported as an error.
                new Service
                {
                    Name = "OracleDatabase",
                    Type = ServiceType.Database
                }
            };

            WriteFiles(component, services);

            var target = new SiteStatusRepository("");

            var result = "";
            using (var writer = new StringWriter())
            {
                target.WriteErrors(writer);
                result = writer.ToString();
            }

            var serializer = new XmlSerializer(typeof(List<SiteStatusIssue>), new Type[] { typeof(SiteStatusIssue) });
            using (var reader = new StringReader(result))
            {
                var actualErrors = (List<SiteStatusIssue>)serializer.Deserialize(reader);
                Assert.IsNotNull(actualErrors);
                Assert.AreEqual(0, actualErrors.Count);
            }
        }
        public void WriteErrors_DirectoryDoesNotExistError()
        {
            DeleteDir();

            var target = new SiteStatusRepository("");
            var result = "";
            using (var writer = new StringWriter())
            {
                target.WriteErrors(writer);
                result = writer.ToString();
            }

            var serializer = new XmlSerializer(typeof(List<SiteStatusIssue>), new Type[] { typeof(SiteStatusIssue) });
            using (var reader = new StringReader(result))
            {
                var actualErrors = (List<SiteStatusIssue>)serializer.Deserialize(reader);
                Assert.IsNotNull(actualErrors);
                Assert.AreNotEqual(0, actualErrors.Count);
            }
        }
        public void WriteErrors_ComponentFormatProblem()
        {
            CreateNeccessaryDir();

            var component = new Component()
            {
                Name = "site-status.Test",
                Version = "0.1.123"
            };

            List<Service> services = new List<Service>()
            {
                new Service
                {
                    Name = "OracleDatabase",
                    Type = ServiceType.Database
                }
            };

            WriteFiles(component, services);

            var directoryInfo = new DirectoryInfo(Path.Combine("", SiteStatusDirectory));
            Assert.IsTrue(directoryInfo.Exists);
            var componentFile = new FileInfo(Path.Combine(directoryInfo.FullName, "Site.ver"));

            var componentContents = "";
            using(var reader = new StreamReader(componentFile.FullName))
            {
                componentContents = reader.ReadToEnd();
                Assert.IsFalse(string.IsNullOrEmpty(componentContents));
            }

            componentContents = componentContents.Replace("Component", "Component12sad");
            using(var writer = new StreamWriter(componentFile.FullName))
            {
                writer.Write(componentContents);
            }

            var target = new SiteStatusRepository("");
            var result = "";
            using (var writer = new StringWriter())
            {
                target.WriteErrors(writer);
                result = writer.ToString();
            }

            var serializer = new XmlSerializer(typeof(List<SiteStatusIssue>), new Type[] { typeof(SiteStatusIssue) });
            using (var reader = new StringReader(result))
            {
                var actualErrors = (List<SiteStatusIssue>)serializer.Deserialize(reader);
                Assert.IsNotNull(actualErrors);
                Assert.AreNotEqual(0, actualErrors.Count);
            }
        }
        public void ResolveStatusMonitor_All()
        {
            CreateNeccessaryDir();

            List<Service> services = new List<Service>()
            {
                new Service
                {
                    Name = "LocalDatabase",
                    Type = ServiceType.Database,
                    // Setting this to a value it won't be.
                    Status = ServiceStatus.Unknown
                },
                new Service
                {
                    Name = "NoDbConnectionMonitor",
                    Type = ServiceType.Database,
                    // Setting this to a value it won't be.
                    Status = ServiceStatus.Up
                }
            };

            var target = new SiteStatusRepository("");

            var yesMonitor = target.ResolveStatusMonitor(services[0]);
            Assert.IsNotNull(yesMonitor);

            var noMonitor = target.ResolveStatusMonitor(services[1]);
            Assert.IsNull(noMonitor);
        }
        public void ResolveServiceStatus_All()
        {
            CreateNeccessaryDir();

            List<Service> services = new List<Service>()
            {
                new Service
                {
                    Name = "LocalDatabase",
                    Type = ServiceType.Database,
                    // Setting this to a value it won't be.
                    Status = ServiceStatus.Unknown
                },
                new Service
                {
                    Name = "NoDbConnectionMonitor",
                    Type = ServiceType.Database,
                    // Setting this to a value it won't be.
                    Status = ServiceStatus.Up
                }
            };

            var target = new SiteStatusRepository("");

            target.ResolveServiceStatus(services[0]);
            Assert.AreEqual(ServiceStatus.Up, services[0].Status);

            target.ResolveServiceStatus(services[1]);
            Assert.AreEqual(ServiceStatus.Unknown, services[1].Status);
        }
        public void NoService_Config()
        {
            CreateNeccessaryDir();

            var component = new Component()
                    {
                        Name = "site-status.Test",
                        Version = "0.1.123"
                    };

            List<Service> services = new List<Service>();

            WriteFiles(component);

            #region PERFORMS THE TEST
            string result = null;
            var target = new SiteStatusRepository("");
            using (var writer = new StringWriter())
            {
                target.Write(writer);
                result = writer.ToString();
            }

            Assert.IsNotNull(result);

            using (var reader = new StringReader(result))
            {
                var actualReport = Report.DeserializeFrom(reader);
                Assert.IsNotNull(actualReport.Component);
                Assert.AreEqual(1, actualReport.Component.Length);
                if (services.Count == 0)
                    Assert.IsNull(actualReport.Service);
                else
                    Assert.AreEqual(services.Count, actualReport.Service.Length);
            }
            #endregion
        }