/// <summary>
        ///   The method indicates if this specific test is actual for Sitecore version of the instance under test.
        /// </summary>
        public virtual bool IsActual(ISolutionResourceContext data, ISitecoreVersion sitecoreVersion)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            Assert.ArgumentNotNull(sitecoreVersion, nameof(sitecoreVersion));

            return(IsActual(sitecoreVersion) && IsActual(data));
        }
Example #2
0
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            var map = data

                      // exclude all CD instances - they do not participate in publishing
                      .Where(x => x.Value.ServerRoles.All(z => z != ServerRole.ContentDelivery))

                      // group all publishing instance setting values to set { 'Pub1': ['Cm1', 'Cm2'], 'Pub2': ['BadCm3'], '': ['BadCm4'] }
                      .GroupBy(x => x.Value.SitecoreInfo.GetSetting(PublishingInstanceSetting))
                      .ToMap(x => x.Key, x => x.ToArray(z => z.Key));

            if (map.Count == 0)
            {
                output.Debug("No publishing instance specified");

                return;
            }

            if (map.Count == 1)
            {
                output.Debug($"Publishing instance is consistent: {map.Keys.FirstOrDefault().EmptyToNull() ?? "N/A"}");

                return;
            }

            var message  = GetMessage(map);
            var detailed = GetDetailed(map);

            output.Error(message, detailed: detailed);
        }
        public override void Process(ISolutionResourceContext solution, ITestOutputContext output)
        {
            var rows = new List <TableRow>();

            foreach (var settingName in solution.SitecoreDefaults.GetSettings().Keys)
            {
                var defaultValue = solution.SitecoreDefaults.GetSetting(settingName);

                if (solution.Values.Any(x => x.SitecoreInfo.GetSetting(settingName) != defaultValue))
                {
                    var columns = new List <Pair>();

                    columns.Add(new Pair("Setting", settingName));
                    columns.AddRange(solution.Values.Select(x => new Pair(x.InstanceName, x.SitecoreInfo.GetSetting(settingName))));
                    columns.Add(new Pair("Default Value", defaultValue.EmptyToNull() ?? "[empty]"));

                    rows.Add(new TableRow(columns));
                }
            }

            if (rows.Any())
            {
                output.Debug(new DetailedMessage(new Text("One or several default Sitecore settings were modified:"), new Table(rows.ToArray())));
            }
        }
        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 void Process(ISolutionResourceContext data, ITestOutputContext output)
 {
     foreach (var instance in data.Values)
     {
         if (IsActual(instance.ServerRoles, instance.SitecoreInfo.SitecoreVersion, instance))
         {
             Process(instance, new ProxyOutputContext(instance.SitecoreInfo.InstanceName, output));
         }
     }
 }
Example #6
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(ISolutionResourceContext data, ITestOutputContext output)
        {
            var patches       = new Map <List <string> >();
            var instanceNames = data.Values.ToArray(x => x.SitecoreInfo.InstanceName);

            foreach (var instance in data.Values)
            {
                Safe(_ => ProcessAssemblies(instance, patches));
                Safe(_ => ProcessConfiguration(instance, patches));
            }

            var assembliesResult = PrintResults(patches, instanceNames);

            if (assembliesResult != null)
            {
                output.Debug(assembliesResult);
            }
        }
Example #8
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)));
            }
        }
        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 bool IsActual(ISolutionResourceContext data, ISitecoreVersion sitecoreVersion)
 {
     return(data.Values.Any(x => IsActual(x.ServerRoles, sitecoreVersion, x)));
 }
 protected override bool IsActual(ISolutionResourceContext data)
 {
     return(data.Values.Any(x => x.SitecoreInfo.Assemblies.Any()));
 }
Example #12
0
 protected override bool IsActual(ISolutionResourceContext data)
 {
     return(data.Count > 1); // test only makes sense if there are several instances
 }
 public override void Process(ISolutionResourceContext data, ITestOutputContext output)
 {
     // ReSharper disable once AssignNullToNotNullAttribute
     output.Debug("ApplicationInfo: " + data.System.ApplicationInfo);
 }
 /// <summary>
 ///   All the test logic must be placed here. Use data parameter to access the resources API, use output parameter to give
 ///   results.
 /// </summary>
 /// <param name="data">An interface to test resources.</param>
 /// <param name="output">An interface to test output.</param>
 public abstract void Process(ISolutionResourceContext data, ITestOutputContext output);
 protected virtual bool IsActual([NotNull] ISolutionResourceContext data)
 {
     return(true);
 }
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            var errors = new List <string>();

            // get a dictionary where key is instance's SitecoreInfo, and values are shared session state providers' XML configuration
            var sharedProviders = data.Values // identifier is a combination of connection string and sessionType value e.g. shared or private or any custom string
                                  .Select(x => new
            {
                x.SitecoreInfo,
                SharedSessionState = x.SitecoreInfo.Configuration.SelectSingleElement("/configuration/sitecore/tracking/sharedSessionState")
            })
                                  .Where(x => x.SharedSessionState != null || // skip those that don't have shared session at all - like publishing instance
                                         ReturnFalse(_ => output.Debug($"Shared session state configuration is missing in {x.SitecoreInfo.InstanceName}")))
                                  .Select(x => new
            {
                x.SitecoreInfo,
                DefaultProviderName = x.SharedSessionState.GetAttribute("defaultProvider")
            })
                                  .Where(x => !string.IsNullOrWhiteSpace(x.DefaultProviderName) ||
                                         ReturnFalse(_ => errors.Add($"Shared session state default provider is not set - in {x.SitecoreInfo.InstanceName}")))
                                  .Select(x => new
            {
                x.SitecoreInfo,
                x.DefaultProviderName,
                Provider = x.SitecoreInfo.Configuration.SelectSingleElement($"/configuration/sitecore/tracking/sharedSessionState/providers/add[@name='{x.DefaultProviderName}']")
            })
                                  .Where(x => x.Provider != null ||
                                         ReturnFalse(_ => errors.Add($"Shared session state default provider {x.DefaultProviderName} cannot be found - in {x.SitecoreInfo.InstanceName}")))
                                  .ToDictionary(
                x => x.SitecoreInfo,
                x => x.Provider);

            // get a dictionary where key is instance's SitecoreInfo, and values are private session state providers' XML configuration
            var privateProviders = data.Values // identifier is a combination of connection string and sessionType value e.g. shared or private or any custom string
                                   .Select(x => new
            {
                x.SitecoreInfo,
                SessionState = x.SitecoreInfo.Configuration.SelectSingleElement("/configuration/sessionState")
            })
                                   .Where(x => x.SessionState != null ||
                                          ReturnFalse(_ => output.Debug($"Private session state configuration is missing in {x.SitecoreInfo.InstanceName}")))
                                   .Select(x => new
            {
                x.SitecoreInfo,
                Mode = x.SessionState.GetAttribute("mode").EmptyToNull() ?? "InProc" // if not specified, InProc is used by default
            })
                                   .Where(x => !x.Mode.Equals("InProc", StringComparison.OrdinalIgnoreCase) ||
                                          ReturnFalse(_ => output.Debug($"Private session state configuration is InProc in {x.SitecoreInfo.InstanceName}")))
                                   .Select(x => new
            {
                x.SitecoreInfo,
                CustomProviderName = x.SitecoreInfo.Configuration.SelectSingleElement("/configuration/sessionState").GetAttribute("customProvider")
            })
                                   .Where(x => !string.IsNullOrWhiteSpace(x.CustomProviderName) ||
                                          ReturnFalse(_ => errors.Add($"Private session state custom provider is not set - in {x.SitecoreInfo.InstanceName}")))
                                   .Select(x => new
            {
                x.SitecoreInfo,
                x.CustomProviderName,
                Provider = x.SitecoreInfo.Configuration.SelectSingleElement($"/configuration/sessionState/providers/add[@name='{x.CustomProviderName}']")
            })
                                   .Where(x => x.Provider != null ||
                                          ReturnFalse(_ => errors.Add($"Private session state custom provider {x.CustomProviderName} cannot be found - in {x.SitecoreInfo.InstanceName}")))
                                   .ToDictionary(
                x => x.SitecoreInfo,
                x => x.Provider);

            if (errors.Any())
            {
                output.CannotRun("There are errors in configuration files that prevent test run. " + new BulletedList(errors));

                return;
            }

            var sharedSessionIdentifiers  = GetIdentifiers(sharedProviders);
            var privateSessionIdentifiers = GetIdentifiers(privateProviders);

            // shared and private identifiers must not intersect
            var done = new List <string>();

            foreach (var privateSessionIdentifier in privateSessionIdentifiers)
            {
                var privateId = privateSessionIdentifier.Key;
                if (done.Contains(privateId))
                {
                    continue;
                }

                foreach (var sharedSessionIdentifier in sharedSessionIdentifiers)
                {
                    var sharedId = sharedSessionIdentifier.Key;
                    if (done.Contains(sharedId))
                    {
                        continue;
                    }

                    var sharedInstancesNames  = sharedSessionIdentifier.Value.Select(x => x.InstanceName);
                    var privateInstancesNames = privateSessionIdentifier.Value.Select(x => x.InstanceName);
                    if (string.Equals(privateId, sharedId, StringComparison.OrdinalIgnoreCase))
                    {
                        output.Error(GetMessage(privateId, privateInstancesNames, sharedInstancesNames));

                        done.Add(privateId);
                    }
                }
            }
        }
Example #17
0
        public override void Process(ISolutionResourceContext data, ITestOutputContext output)
        {
            var inprocMap        = new Map <string[]>();
            var inconsistencyMap = new Map <Map>();

            var clusters = data.Values
                           .Where(x => x.ServerRoles.Any(r => r == ServerRole.ContentDelivery))
                           .Where(x => x.SitecoreInfo.IsAnalyticsEnabled)
                           .GroupBy(i => i.SitecoreInfo.GetSetting("Analytics.ClusterName").EmptyToNull() ?? "[empty]")
                           .ToDictionary(x => x.Key, x => x.ToArray());

            foreach (var cluster in clusters)
            {
                var clusterName = cluster.Key;
                var instances   = cluster.Value;

                if (instances.Length == 0)
                {
                    throw new NotImplementedException("impossible");
                }

                if (instances.Length == 1)
                {
                    // single CD instance in cluster means we don't need to check anything
                    output.Debug($"Cluster {clusterName.EmptyToNull() ?? "[empty]"} has single instance");

                    continue;
                }

                var defaultProviders = instances
                                       .Select(x => new
                {
                    x.SitecoreInfo,
                    DefaultProviderName = x.SitecoreInfo.Configuration.SelectSingleElement("/configuration/sitecore/tracking/sharedSessionState").GetAttribute("defaultProvider")
                })
                                       .Select(x => new
                {
                    x.SitecoreInfo,
                    DefaultProvider = x.SitecoreInfo.Configuration.SelectSingleElement($"/configuration/sitecore/tracking/sharedSessionState/providers/add[@name='{x.DefaultProviderName}']")
                })
                                       .Select(x => new
                {
                    x.SitecoreInfo,
                    x.DefaultProvider,
                    DefaultProviderType = TypeRef.Parse(x.DefaultProvider.GetAttribute("type"))
                })
                                       .ToArray();

                // check that all instances don't use InProc

                var gr = defaultProviders
                         .GroupBy(x => x.DefaultProviderType)
                         .ToArray();

                var instancesInProc = gr
                                      .FirstOrDefault(x => x.Key.Equals(InProcType))?
                                      .Select(x => x.SitecoreInfo.InstanceName)
                                      .ToArray();

                if (instancesInProc != null)
                {
                    inprocMap.Add(clusterName, instancesInProc);

                    continue;
                }

                // check that all instances use same shared session

                var data1 = defaultProviders
                            .Select(x => new
                {
                    x.SitecoreInfo,
                    ConnectionStringName = x.DefaultProvider.GetAttribute("connectionString")
                })
                            .ToMap(
                    x => x.SitecoreInfo.InstanceName,
                    x => x.SitecoreInfo.GetConnectionString(x.ConnectionStringName));

                var map = data1
                          .GroupBy(x => x.Value)
                          .ToArray();

                if (map.Length <= 1)
                {
                    output.Debug($"Cluster {clusterName} has consistent shared session configuration, connection string: {map.FirstOrDefault()?.Key}");

                    continue;
                }

                inconsistencyMap.Add(clusterName, data1);
            }

            if (inprocMap.Any())
            {
                var message = new ShortMessage(
                    new Text($"InProc shared session mode is used among Sitecore instances which is not supported."),
                    new BulletedList(inprocMap.Keys.ToArray(clusterName => new Container(
                                                                new Text($"Cluster: {clusterName}"),
                                                                BulletedList.Create(clusters[clusterName], instance => $"{instance.SitecoreInfo.InstanceName} - {IsAffected(inprocMap, clusterName)}")))));

                output.Error(message);
            }

            if (inconsistencyMap.Any())
            {
                var message = GetMessage(inconsistencyMap);

                output.Error(message);
            }
        }