Пример #1
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var configuration    = data.SitecoreInfo.Configuration;
            var frequencyElement = configuration.SelectSingleNode("/configuration/sitecore/scheduling/frequency") as XmlElement;
            var text             = frequencyElement?.InnerText;

            if (string.IsNullOrEmpty(text))
            {
                // default 00:01:00 frequency is used
                return;
            }

            TimeSpan frequency;

            if (!TimeSpan.TryParse(text, out frequency))
            {
                output.Warning(WrongFrequencyMessage);

                // default 00:01:00 frequency is used
                return;
            }

            if (frequency.Ticks == 0)
            {
                output.Warning(GetSchedulingStoppedMessage(frequencyElement));
            }
            else if (frequency.Hours >= 1)
            {
                output.Warning(GetShedulingRareMessage(frequencyElement));
            }
        }
Пример #2
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            var duplicates     = new Map <List <string> >();
            var resultConfig   = data.SitecoreInfo.Configuration;
            var configurations = resultConfig.SelectElements(ContentSearchXPath + "/*").Select(x => x.Name).Distinct().ToArray();

            foreach (var configuration in configurations)
            {
                var configurationElements = resultConfig.SelectElements($"{ContentSearchXPath}/{configuration}");
                if (configurationElements.Length > 1)
                {
                    var list = duplicates.GetOrAdd(configuration, new List <string>());
                    list.AddRange(configurationElements.Select(x => x.ToString(XmlPrintMode.HeaderOnly)));
                }
            }

            if (duplicates.Any())
            {
                var shortMessage = "There are duplicates in ContentSearch configuration nodes that may lead to unpredictable behavior.";
                var detailed     = new DetailedMessage(
                    new Text("The following ContentSearch configurations are duplicated:"),
                    new BulletedList(duplicates.Select(x => new Container(
                                                           new Text(x.Key),
                                                           new BulletedList(x.Value.Select(z => new Code(z)))
                                                           ))),
                    new Text("To resolve, rewise the configuration files and check the difference between defintions."));

                output.Warning(shortMessage, null, detailed);
            }
        }
 public override void Process(IInstanceResourceContext data, ITestOutputContext output)
 {
     if (!data.SitecoreInfo.GetBoolSetting("Analytics.AutoDetectBots"))
     {
         output.Warning(ErrorMessage);
     }
 }
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var defaultAssemblies = data.SitecoreDefaults.Assemblies;

            var resultsMap = new Map <Map>();

            foreach (var defaultAssembly in defaultAssemblies.Values)
            {
                if (defaultAssembly == null)
                {
                    continue;
                }

                var fileName = defaultAssembly.FileName;

                // workaround for sspg-49
                if (fileName.Equals("ninject.dll", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var assemblyMap = new Map();

                var expectedFileVersion = defaultAssembly.FileVersion;
                assemblyMap.Add("Version", expectedFileVersion);

                var good = true;
                foreach (var instance in data.Values)
                {
                    var result = Process(fileName, instance, defaultAssembly);
                    if (string.IsNullOrEmpty(result))
                    {
                        assemblyMap.Add(instance.InstanceName, "OK");
                    }
                    else
                    {
                        assemblyMap.Add(instance.InstanceName, result);
                        good = false;
                    }
                }

                if (!good)
                {
                    resultsMap.Add(fileName, assemblyMap);
                }
            }

            if (resultsMap.Count > 0)
            {
                output.Warning("There is an inconsistency in assembly files",
                               detailed: new DetailedMessage(new Table(resultsMap.ToArray(x =>
                                                                                          new TableRow(
                                                                                              new[] { new Pair("Assembly", x.Key) }
                                                                                              .Concat(x.Value.Select(c => new Pair(c.Key, c.Value)))
                                                                                              .ToArray())))));
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            var reportingSecondary = data.Databases.Sql.DatabaseNames.Contains(ConnectionString);

            if (reportingSecondary)
            {
                output.Warning(ErrorMessage);
            }
        }
Пример #6
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            if (data.SitecoreInfo.GetSetting("Analytics.DefaultDefinitionDatabase") != "web")
            {
                output.Warning(ErrorMessage);
            }
        }
Пример #7
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            if (data.WebServer.Server.OperationSystemBitness != FrameworkBitness.x64)
            {
                output.Warning("The 32-bit Operation System is used, upgrade to 64-bit OS is recommended. Read more in Installation Guide, section Sitecore Hosting Environment Requirements");
            }
        }
        /// <summary>
        ///   The method for claiming KB issue is applicable to the solution.
        /// </summary>
        protected void Report([NotNull] ITestOutputContext output, string message = null)
        {
            Assert.ArgumentNotNull(output, nameof(output));

            if (!string.IsNullOrEmpty(message))
            {
                if (char.IsLower(message[0]))
                {
                    message = message.Substring(0, 1).ToUpper() + message.Substring(1);
                }

                output.Warning(string.Format(ErrorFormatWithMessage, KbNumber, message, KbName), Link);
            }
            else
            {
                output.Warning(string.Format(ErrorFormat, KbNumber), Link);
            }
        }
Пример #9
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            if (data.SitecoreInfo.GetBoolSetting("Caching.DisableCacheSizeLimits"))
            {
                output.Warning("All cache size limits are disabled. It can potentially cause significant performance degradation and OutOfMemoryException exception. It is recommended to disable this setting. Check CMS Performance Tuning Guide document for details.");
            }
        }
Пример #10
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var configuration = data.SitecoreInfo.Configuration;
            var handler       = configuration.SelectElements(XPath).FirstOrDefault();

            if (handler == null)
            {
                output.Warning(MessageNoHandlerElement);
                return;
            }

            if (handler.ChildNodes.Count == 0)
            {
                output.Warning(MessageNoSitesElement);
                return;
            }

            var sitesElement = handler.ChildNodes[0];

            if (sitesElement == null)
            {
                output.Warning(MessageNoSitesElement);
                return;
            }

            // siteNamesInHandler = ["website"] in default Sitecore configuration
            var siteNamesInHandler = sitesElement.ChildNodes.OfType <XmlNode>().Where(x => x != null).Select(x => x.InnerText).ToArray();

            var actualSiteElements = configuration.SelectElements("/configuration/sitecore/sites/site");
            var actualSiteNames    = actualSiteElements.Select(x => x.GetAttribute("name"));

            // frontendSiteNames = ["website"] in default Sitecore configuration
            var frontendSiteNames = actualSiteNames.Where(x => !SystemSites.Contains(x));

            foreach (var frontendSiteName in frontendSiteNames)
            {
                if (frontendSiteName != null && !siteNamesInHandler.Contains(frontendSiteName))
                {
                    output.Warning(GetErrorMessage(frontendSiteName));
                }
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var warnLogEntries = data.Logs.GetSitecoreLogEntries(LogLevel.Warn);

            if (warnLogEntries.Any(entry => entry.Message.StartsWith("Counter category '") && entry.Message.Contains("' does not exist on this server. Using temporary public counter for '")))
            {
                output.Warning(CountersNotInstalledMessage, Link);
            }
        }
Пример #12
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var ramMemory = data.WebServer.Server.RamMemoryTotal;

            if (ramMemory.GB < Recommended)
            {
                output.Warning(Message);
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var configuration = data.SitecoreInfo.Configuration;
            var excludeRobots = configuration.SelectSingleNode("/configuration/sitecore/analyticsExcludeRobots");

            if (excludeRobots == null)
            {
                output.Warning(ErrorMessage);
            }
        }
Пример #14
0
        public override void Process(ISolutionResourceContext solution, ITestOutputContext output)
        {
            var instancesWithWrongGlobalAsax = new List <string>();
            var instancesWithUnclear         = new Map();

            foreach (var data in solution.Values)
            {
                var originalGlobalAsaxFile = data.SitecoreInfo.GlobalAsaxFile;
                var globalAsaxFile         = originalGlobalAsaxFile.Replace(" ", string.Empty).ToLower().Replace("'", "\"");

                // If inherits points to System.Web.HttpApplication, output an error.
                if (globalAsaxFile.Contains("Inherits=\"System.Web.HttpApplication\"".ToLower()))
                {
                    instancesWithWrongGlobalAsax.Add(data.InstanceName);

                    continue;
                }

                // If inherits is missing, output an error.
                if (!globalAsaxFile.Contains("Inherits".ToLower()))
                {
                    instancesWithWrongGlobalAsax.Add(data.InstanceName);

                    continue;
                }

                // If inherits points to something else, output a warning that user needs to check manually if class inherits from Sitecore.Web.Application.
                if (!(globalAsaxFile.Contains("Inherits=\"Sitecore.Web.Application\"".ToLower()) ||
                      globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.CastleWindsorIntegration.WindsorApplication\"".ToLower()) ||
                      globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.AutoFacIntegration.AutoFacApplication\"".ToLower()) ||
                      globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.NinjectIntegration.NinjectApplication\"".ToLower()) ||
                      globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.StructureMapIntegration.StructureMapApplication\"".ToLower()) ||
                      globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.UnityIntegration.UnityApplication\"".ToLower())))
                {
                    instancesWithUnclear.Add(data.InstanceName, originalGlobalAsaxFile);
                }
            }

            if (instancesWithWrongGlobalAsax.Count > 0)
            {
                output.Error(SystemWebMessage, detailed: new DetailedMessage(new BulletedList(instancesWithWrongGlobalAsax)));
            }

            if (instancesWithUnclear.Count > 0)
            {
                output.Warning(
                    new ShortMessage(
                        new Text(SystemWebMessage),
                        new Text(Comment)),
                    detailed: new DetailedMessage(new Table(instancesWithUnclear.ToArray(x => new TableRow(new Pair("Instance", x.Key), new Pair("Value", x.Value))))));
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var coresCount = data.WebServer.Server.CpuCoresCount;

            var message = $"Your server has {coresCount} CPU cores, which is lower than the recommended minimum. Please review the hardware recommendations for Sitecore products.";

            if (coresCount <= 2)
            {
                output.Warning(message);
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var ecmVersion = EcmHelper.GetEcmVersion(data);

            Assert.IsNotNull(ecmVersion);

            var majorMinor = ecmVersion.MajorMinorInt;

            if (majorMinor >= 31)
            {
                var httpHandlersNode = data.SitecoreInfo.Configuration.SelectSingleNode($"/configuration/system.web/httpHandlers/add[@path='{ecmSpeakHandlerPath}']");
                if (httpHandlersNode != null)
                {
                    output.Warning(GetErrorMessage("<httpHandlers>", false));
                }
                var handlersNode = data.SitecoreInfo.Configuration.SelectSingleNode($"/configuration/system.webSerber/handlers/add[@path='{ecmSpeakHandlerPath}']");
                if (handlersNode != null)
                {
                    output.Warning(GetErrorMessage("<handlers>", false));
                }
            }
            if (majorMinor == 22 || majorMinor == 30)
            {
                var httpHandlersNode = data.SitecoreInfo.Configuration.SelectSingleNode($"/configuration/system.web/httpHandlers/add[@path='{ecmSpeakHandlerPath}']");
                if (httpHandlersNode == null)
                {
                    output.Warning(GetErrorMessage("<httpHandlers>", true));
                }
                var handlersNode = data.SitecoreInfo.Configuration.SelectSingleNode($"/configuration/system.webSerber/handlers/add[@path='{ecmSpeakHandlerPath}']");
                if (handlersNode == null)
                {
                    output.Warning(GetErrorMessage("<handlers>", true));
                }
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            var moments       = new List <DateTime>();
            var startMessages = data.Logs.GetSitecoreLogEntries(LogLevel.Info).Where(x => x.Message.StartsWith(StartMessage, StringComparison.OrdinalIgnoreCase));

            foreach (var entry in startMessages)
            {
                var moment          = entry.Date;
                var entries         = data.Logs.GetSitecoreLogEntries(LogLevel.All, moment - ShutdownTimeout, moment);
                var entriesToSearch = GetEntriesToSearch(entries, entry).ToArray();

                // if cold start
                if (entriesToSearch.Length <= 5)
                {
                    continue;
                }

                if (entriesToSearch.Any(x => x.Level == LogLevel.Warn && x.Message.StartsWith(ShutdownMessage)))
                {
                    continue;
                }

                var left = MaxEntriesCount - entriesToSearch.Length;
                if (left > 0)
                {
                    var extraEntries = data.Logs.GetSitecoreLogEntries(LogLevel.All, DateTime.MinValue, moment - ShutdownTimeout).ToArray();

                    if (extraEntries.Length > left)
                    {
                        extraEntries = extraEntries.Take(left).ToArray();
                    }

                    if (extraEntries.Any(x => x.Level == LogLevel.Warn && x.Message.StartsWith(ShutdownMessage)))
                    {
                        continue;
                    }
                }

                moments.Add(moment);
            }

            if (moments.Count > 0)
            {
                var message = "There are potential hard application restarts have been detected.";

                output.Warning(message, detailed: GetMessage(moments));
            }
        }
Пример #18
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var core = data.Databases.Sql["core"];

            if (core == null)
            {
                output.Error("The core database is not found");

                return;
            }

            var eventQueueSize = core.CountRows("EventQueue");

            if (eventQueueSize == 0)
            {
                return;
            }

            var propertyChangedEventsCount = core.CountRows("EventQueue", Condition);

            Assert.IsTrue(propertyChangedEventsCount >= 0, "propertyChangedEventsCount >= 0");
            Assert.IsTrue(eventQueueSize > 0, "eventQueueSize > 0");

            var ratio = propertyChangedEventsCount * 100 / eventQueueSize;

            if (ratio < RateLow)
            {
                return;
            }

            var message = $"The EventQueue table is more than {RateMedium}% filled with the PropertyChangedRemoteEvent records.";

            if (ratio < RateMedium)
            {
                output.Debug(message);
                return;
            }

            if (ratio < RateHigh)
            {
                output.Warning(message, Link);
                return;
            }

            output.Error(message, Link);
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var driveName = data.WebServer.Site.WebRoot.Root.Name;
            var size      = data.FileSystem.Drives.GetAvailableFreeSpace(driveName);

            if (size.GB < Minimum)
            {
                output.Error(GetErrorMessage(size, driveName));
            }
            else if (size.GB < Recommended)
            {
                output.Warning(GetWarningMessage(size, driveName));
            }
        }
Пример #20
0
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            var files     = new List <string>();
            var identical = CollectionHelper.AreIdenticalByPairs(
                data.Values.ToArray(),
                (instanceA, instanceB) =>

                // compare IncludeFiles of all instances to ensure they are identical
                CollectionHelper.AreIdentical(
                    instanceA.SitecoreInfo.IncludeFiles,
                    instanceB.SitecoreInfo.IncludeFiles,
                    (nameA, nameB) => string.Equals(nameA, nameB, StringComparison.OrdinalIgnoreCase),
                    (fileA, fileB) =>
            {
                if (fileA == null)
                {
                    Assert.IsNotNull(fileB);

                    files.Add(fileB.FilePath.Substring(fileB.FilePath.IndexOf("App_Config")));
                    return(false);
                }

                if (fileB == null)
                {
                    Assert.IsNotNull(fileA);

                    files.Add(fileA.FilePath.Substring(fileA.FilePath.IndexOf("App_Config")));
                    return(false);
                }

                if (!string.Equals(fileA.RawText, fileB.RawText, StringComparison.Ordinal))
                {
                    files.Add(fileA.FilePath.Substring(fileA.FilePath.IndexOf("App_Config")));
                    return(false);
                }

                return(true);
            }));

            if (!identical)
            {
                output.Warning(ShortMessage, detailed: new DetailedMessage(new BulletedList(files)));
            }
        }
Пример #21
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var config = data.SitecoreInfo.Configuration;
            var verboseLoggingElement = config.SelectSingleNode(XPath + "[@name='" + AttributeName + "']") as XmlElement;

            if (verboseLoggingElement == null)
            {
                return;
            }

            var verboseLoggingValue = verboseLoggingElement.GetAttribute("value");

            if (verboseLoggingValue.Equals("true", StringComparison.OrdinalIgnoreCase))
            {
                output.Warning(MessageVerboseLoggingEnabled);
            }
        }
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            var numberOfSearchEnabledInstances = data.Values.Count(x => x.SitecoreInfo.ContentSearchIndexes.Any());

            if (numberOfSearchEnabledInstances < 2)
            {
                // if total number of Sitecore instances that actually use search is 1 or 0, we don't need to offer Solr
                return;
            }

            var index2instances = new Map <List <string> >();

            foreach (var instance in data.Values)
            {
                var luceneIndexes = instance.SitecoreInfo.ContentSearchIndexes.Values.Where(i => i.SearchProvider == SearchProvider.Lucene).ToArray();
                foreach (var index in luceneIndexes)
                {
                    var instances = index2instances.GetOrAdd(index.Id, new List <string>());
                    Assert.IsNotNull(instances);

                    instances.Add(instance.SitecoreInfo.InstanceName);
                }
            }

            if (index2instances.Any())
            {
                var rows = new List <TableRow>();
                foreach (var indexName in index2instances.Keys)
                {
                    var instances = index2instances[indexName];
                    rows.Add(new TableRow(new[] { new Pair("Index", indexName) }
                                          .Concat(instances.Select(z => new Pair(z, "Lucene")))));
                }

                var text = "The solution is configured to use Lucene search engine for the number of Content Search indexes listed below. It is highly " +
                           "recommended to consider upgrading your solution to use Solr, as Lucene cannot deliver acceptable level of stability, consistency and maintainability.";

                var message  = new ShortMessage(new Text(text));
                var detailed = new DetailedMessage(new Table(rows.ToArray()));

                output.Warning(message, detailed: detailed);
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var config = data.SitecoreInfo.Configuration;

            var sites = config.SelectElements(SiteXPath);

            if (sites.Any())
            {
                output.Warning(GetErrorMessage("<sites>"));
            }

            var idTable = config.SelectElements(IdTableXPath);

            if (idTable.Any())
            {
                output.Warning(GetErrorMessage("<IDTable>"));
            }

            var databases = config.SelectElements(DatabaseXPath);

            if (databases.Any())
            {
                output.Warning(GetErrorMessage("<databases>"));
            }

            var search = config.SelectElements(SearchXPath);

            if (search.Any())
            {
                output.Warning(GetErrorMessage("<search>"));
            }

            var agent1 = config.SelectElements(SchedulingXPath1);

            if (agent1.Any())
            {
                output.Warning(GetErrorMessage("<scheduling>"));
            }

            var agent2 = config.SelectElements(SchedulingXPath2)
                         .Where(x => x != null && x.InnerText == "master");

            if (agent2.Any())
            {
                output.Warning(GetErrorMessage("<scheduling>"));
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            // Get resources first
            var configuration = data.SitecoreInfo.Configuration;

            // Perform checks
            var compilation = configuration.SelectSingleNode(XPath) as XmlElement;

            if (compilation == null)
            {
                return;
            }

            var debug = compilation.GetAttribute("debug");

            if (debug.Equals("true", StringComparison.OrdinalIgnoreCase))
            {
                output.Warning(MessageCompilationDebugEnabled);
            }
        }
Пример #25
0
    public override void Process(IInstanceResourceContext data, ITestOutputContext output)
    {
      Assert.ArgumentNotNull(data, nameof(data));

      var info = data.SitecoreInfo;
      var defaults = info.SitecoreDefaults;
      var defaultCachesPerDatabase = new Map<Map<CacheSizeDetails>>();
      var belowDefaultCachesPerDatabase = new Map<Map<CacheSizeDetails>>();
      foreach (var database in info.GetDatabases().Values)
      {
        if (database.Name == "filesystem")
        {
          continue;
        }

        var defaultDatabase = defaults.GetDatabases().TryGetValue(database.Name);
        if (defaultDatabase == null)
        {
          continue;
        }

        Process(info, output, database, defaultDatabase, defaultCachesPerDatabase, belowDefaultCachesPerDatabase);
      }

      if (defaultCachesPerDatabase.Any())
      {
        var message = "One or several Sitecore caches are not tuned up and use default settings which may lead to performance degradation";

        output.Warning(message, detailed: GetMessage(defaultCachesPerDatabase));
      }

      if (belowDefaultCachesPerDatabase.Any())
      {
        var message = "One or several Sitecore caches are use custom configuration which is below the minimum recommended values (set up by default) which may lead to performance degradation.";

        output.Error(message, detailed: GetMessage(belowDefaultCachesPerDatabase));
      }
    }
Пример #26
0
        private static void ProcessProperties([NotNull] IInstanceResourceContext data, ITestOutputContext output, [NotNull] IEnumerable <Property> properties, [NotNull] string pathFormat, params object[] arguments)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            Assert.ArgumentNotNull(properties, nameof(properties));
            Assert.ArgumentNotNull(pathFormat, nameof(pathFormat));

            // defaults
            arguments = arguments ?? new object[0];

            var path = arguments.Length > 0 ? string.Format(pathFormat, arguments) : pathFormat;

            foreach (var property in properties)
            {
                Assert.IsNotNull(property, "property");

                var actual   = property.Actual;
                var expected = property.Default;
                if (actual == null && expected == null)
                {
                    continue;
                }

                if (actual != null && actual.ToString().Equals((expected ?? string.Empty).ToString(), StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }

                var message = $"Database schema mismatch: {path}.{property.Title}. Expected: {expected ?? "<null>"}. Actual: {actual ?? "<null>"}.";
                if (property.IsError)
                {
                    output.Error(message);
                }
                else
                {
                    output.Warning(message);
                }
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var enableHttpCache = data.SitecoreInfo.GetBoolSetting("ContentSearch.Solr.EnableHttpCache");

            if (!enableHttpCache)
            {
                return;
            }

            var indexes = data.SitecoreInfo.ContentSearchIndexes.Values;

            var cores = new List <string>(indexes.Count());

            foreach (var index in indexes)
            {
                var core = index.Configuration.SelectElements(@"//param[@desc='core']").First();
                cores.Add(core.InnerText);
            }

            cores = cores.Distinct().ToList();
            var count = cores.Count;

            if (count == 0 || count == 1 && cores[0] != "$(id)")
            {
                return;
            }

            var globalAsaxFile = data.SitecoreInfo.GlobalAsaxFile;

            if (globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.NinjectIntegration.NinjectApplication\"") ||
                globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.StructureMapIntegration.StructureMapApplication\"") ||
                globalAsaxFile.Contains("Inherits=\"Sitecore.ContentSearch.SolrProvider.UnityIntegration.UnityApplication\""))
            {
                output.Warning(WarningMsg, Link);
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            var obsoleteConfigurations = GetObsoleteConfigurations(data).ToArray();

            foreach (var configuration in obsoleteConfigurations)
            {
                var configurationName  = configuration.Name;
                var configurationFiles = configuration.Files;

                foreach (var configurationFile in data.SitecoreInfo.IncludeFiles.Values)
                {
                    var configurationElements = configurationFile.Configuration.SelectElements($"{ContentSearchXPath}/{configurationName}");
                    if (configurationElements.Any(x => TypeRef.Parse(x.GetAttribute("type")) == configuration.Type))
                    {
                        configurationFiles.Add(configurationFile.FilePath.Substring(configurationFile.FilePath.IndexOf("App_Config")));
                    }
                }
            }

            if (obsoleteConfigurations.Any(x => x.Files.Any()))
            {
                var defaultType = TypeRef.Parse(data.SitecoreInfo.SitecoreDefaults.Configuration.SelectSingleElement($"{ContentSearchXPath}/configuration").GetAttribute("type"));
                Assert.IsNotNull(defaultType);

                var shortMessage = "ContentSearch configuration uses obsolete LuceneSearchConfiguration that may lead to unpredictable behavior.";
                var detailed     = new DetailedMessage(
                    new Text("The following ContentSearch configurations are obsolete:"),
                    new BulletedList(obsoleteConfigurations.Select(x =>
                                                                   new Container(
                                                                       new Code(x.Definition.ToString(XmlPrintMode.HeaderOnly)),
                                                                       new BulletedList(x.Files)))),
                    new Text("To resolve, change configuration type either to "),
                    new Code(defaultType.ToString()),
                    new Text(", or to a custom class that inherits from it."));

                output.Warning(shortMessage, null, detailed);
            }
        }
        protected bool CheckPhysicalFolder([NotNull] IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var sites = data.SitecoreInfo.Configuration.SelectElements("/configuration/sitecore/sites/site");

            foreach (var siteElement in sites)
            {
                if (siteElement == null)
                {
                    continue;
                }

                var name = siteElement.GetAttribute("name");
                if (DefaultSites.Contains(name))
                {
                    continue;
                }

                var folder = siteElement.GetAttribute("physicalFolder");
                if (string.IsNullOrEmpty(folder))
                {
                    continue;
                }

                if (folder == "/")
                {
                    continue;
                }

                output.Warning(GetPhysicalFolderSettingMessage(name, folder));

                return(false);
            }

            return(true);
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var fieldsConfigIgnored   = new HashSet <string>();
            var fieldsAnalyzerIgnored = new HashSet <string>();

            var config   = data.SitecoreInfo.Configuration;
            var sitecore = config.SelectSingleNode("/configuration/sitecore");

            if (sitecore == null)
            {
                return;
            }

            var defaultIndexConfigurationPath = data.SitecoreInfo.GetSetting("ContentSearch.DefaultIndexConfigurationPath");
            var defaultFieldMapPath           = defaultIndexConfigurationPath + "/fieldMap";
            var defaultFieldNames             = ExtractFieldNames(config.SelectElements(@"/configuration/sitecore/" + defaultFieldMapPath).FirstOrDefault());

            var defaultFieldNamesAreVerified = false;
            var indexes = config.SelectElements(@"/configuration/sitecore/contentSearch/configuration/indexes/*");

            foreach (var index in indexes)
            {
                if (!index.HasAttribute("type") || !index.GetAttribute("type").Contains("Lucene"))
                {
                    continue;
                }

                var configuration = index.SelectElements(@"configuration").FirstOrDefault();
                if (configuration == null)
                {
                    if (defaultFieldNamesAreVerified)
                    {
                        continue;
                    }

                    VerifyFieldNames(defaultFieldNames, fieldsConfigIgnored, fieldsAnalyzerIgnored);
                    defaultFieldNamesAreVerified = true;
                }
                else
                {
                    var fieldMap = configuration.SelectElements("fieldMap").FirstOrDefault();
                    if (fieldMap == null)
                    {
                        if (defaultFieldNamesAreVerified)
                        {
                            continue;
                        }

                        VerifyFieldNames(defaultFieldNames, fieldsConfigIgnored, fieldsAnalyzerIgnored);
                        defaultFieldNamesAreVerified = true;
                    }
                    else
                    {
                        if (fieldMap.HasAttribute("ref"))
                        {
                            var referencedFieldMapPath = @"/configuration/sitecore/" + fieldMap.GetAttribute("ref");

                            Map <XmlElement> mergedFieldNames;
                            if (referencedFieldMapPath.Equals(defaultFieldMapPath, StringComparison.InvariantCulture))
                            {
                                mergedFieldNames = ExtractFieldNames(fieldMap).Concat(defaultFieldNames).ToMap(kvp => kvp.Key, kvp => kvp.Value);
                            }
                            else
                            {
                                var referencedFieldMap = config.SelectElements(referencedFieldMapPath).FirstOrDefault();
                                mergedFieldNames = ExtractFieldNames(fieldMap).Concat(ExtractFieldNames(referencedFieldMap)).ToMap(kvp => kvp.Key, kvp => kvp.Value);
                            }

                            VerifyFieldNames(mergedFieldNames, fieldsConfigIgnored, fieldsAnalyzerIgnored);
                        }
                        else
                        {
                            var fieldNames = ExtractFieldNames(fieldMap);
                            VerifyFieldNames(fieldNames, fieldsConfigIgnored, fieldsAnalyzerIgnored);
                        }
                    }
                }
            }

            if (fieldsConfigIgnored.Count > 0)
            {
                output.Warning("Configuration of the following field(s) is ignored", Link, new DetailedMessage(new BulletedList(fieldsConfigIgnored)));
            }

            if (fieldsAnalyzerIgnored.Count > 0)
            {
                output.Warning("Analyzer of the following field(s) is ignored", Link, new DetailedMessage(new BulletedList(fieldsAnalyzerIgnored)));
            }
        }