Beispiel #1
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);
        }
Beispiel #2
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var xdbEnabled = data.SitecoreInfo.IsAnalyticsEnabled;
            var name       = "reporting";
            var reporting  = data.Databases.Sql[name];

            if (reporting == null)
            {
                var message = $"The {name} connection string is not presented in the ConnectionStrings.config file";
                if (xdbEnabled)
                {
                    output.Error(message);
                }
                else
                {
                    output.Debug(message + ", but that's okay since xdb is disabled");
                }

                return;
            }

            var schema = reporting.Schema;

            var sb = new List <string>();

            // check tables
            foreach (var tableName in TableNames)
            {
                if (!schema.Tables.ContainsKey(tableName))
                {
                    sb.Add($"{name}.Tables.dbo.{tableName}");
                }
            }

            foreach (var procedureName in ProcedureNames)
            {
                if (!schema.StoredProcedures.ContainsKey(procedureName))
                {
                    sb.Add($"{name}.Programmability.Stored Procedures.dbo.{procedureName}");
                }
            }

            if (sb.Count > 0)
            {
                var message = "One or several objects are missing in the reporting database. This may happen if EXM SQL script was not run or ended with error. Please refer to EXM installation guide for more details.";
                if (xdbEnabled)
                {
                    output.Error(message, detailed: new DetailedMessage(new BulletedList(sb)));
                }
                else
                {
                    output.Debug(message);
                }
            }
        }
        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())));
            }
        }
Beispiel #4
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            var defaultDatabases = data.SitecoreInfo.SitecoreDefaults.SqlDatabases;
            var databases        = data.Databases.Sql.All;

            foreach (var database in databases)
            {
                if (database == null)
                {
                    continue;
                }

                try
                {
                    ProcessDatabase(database, defaultDatabases, data, output);
                }
                catch (ResourceNotAvailableException)
                {
                    throw new DatabaseResourceNotAvailableException();
                }
                catch (Exception ex)
                {
                    var message = $"Unhandled exception happened during processing {database.Name} database. Find details in log file.";

                    output.Debug(ex, message);
                    output.CannotRun(message);
                }
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));
            Assert.ArgumentNotNull(output, nameof(output));

            var errorsDetected = false;

            //if (CheckFiles(data, output))
            //{
            //  errorsDetected = true;
            //}

            if (CheckLinkProvider(data, output))
            {
                errorsDetected = true;
            }

            if (CheckPhysicalFolder(data, output))
            {
                errorsDetected = true;
            }

            if (!errorsDetected)
            {
                output.Debug($"For more troubleshooting steps in case of Page Not Found errors in links from ECM messages please refer to the article: {Link}");
            }
        }
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

            foreach (var item in data.SitecoreInfo.ModulesInformation.IncorrectlyInstalledModules)
            {
                if (!item.Value.Any())
                {
                    continue;
                }

                var version = item.Value.Select(
                    ri =>
                    new
                {
                    ri.Release,
                    Data =
                        ri.Assemblies
                        .Select(x => new
                    {
                        x.FileName,
                        Expected = x.FileVersion,
                        Actual   = data.SitecoreInfo.Assemblies.TryGetValue(x.FileName)?.FileVersion ?? "[missing]"
                    })
                        .Where(x => x.Actual != x.Expected)
                })

                              .Select(ri => new
                {
                    ri.Release,
                    ri.Data,
                    Count = ri.Data.Count(),
                })

                              .Where(z => z.Data.Count(x => x.Actual != "[missing]" && x.FileName.StartsWith("Sitecore.", StringComparison.OrdinalIgnoreCase)) > 0) // with at least one existing Sitecore assembly in the list
                              .OrderBy(z => z.Count)
                              .FirstOrDefault();

                if (version == null)
                {
                    continue;
                }

                output.Debug(
                    new DetailedMessage(new Text($"An inconsistent module was detected: "),
                                        new BoldText(item.Key + " " + version.Release.Version.MajorMinorUpdate),
                                        new Table(
                                            version.Data
                                            .ToArray(x =>
                                                     new TableRow(
                                                         new Pair("Assembly", x.FileName),
                                                         new Pair("Actual Version", x.Actual),
                                                         new Pair("Default Version", x.Expected))))));
            }
        }
Beispiel #7
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(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);
            }
        }
Beispiel #9
0
        public override void Process(IInstanceResourceContext data, ITestOutputContext output)
        {
            Assert.ArgumentNotNull(data, nameof(data));

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

            if (sitecore == null)
            {
                return;
            }

            var indexes = config.SelectElements(@"/configuration/sitecore/contentSearch/configuration/indexes/index");

            foreach (var index in indexes)
            {
                if (index == null)
                {
                    continue;
                }

                var indexDatabases = index.SelectElements("locations/*/Database").Select(x => x.InnerText).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToArray();
                if (!indexDatabases.Any())
                {
                    continue;
                }

                var indexName             = index.GetAttribute("id");
                var indexStrategiesXPaths = index.SelectElements("strategies/strategy").Select(x => x.GetAttribute("ref")).Distinct().ToArray();
                foreach (var strategyXPath in indexStrategiesXPaths)
                {
                    if (string.IsNullOrEmpty(strategyXPath))
                    {
                        output.Debug(GetIndexStrategiesCorruptedMessage(indexName));
                        break;
                    }

                    var strategy = sitecore.SelectSingleNode(strategyXPath);
                    if (strategy == null)
                    {
                        output.Debug(GetIndexStrategiesCorruptedMessage(indexName));
                        continue;
                    }

                    var strategyDatabase = strategy.SelectSingleNode("param[@desc='database']").With(x => x.InnerText);

                    if (strategy.Name.Equals("manual", StringComparison.InvariantCultureIgnoreCase))
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(strategyDatabase))
                    {
                        output.Debug(GetStrategyCorruptedMessage(strategy.Name));
                        continue;
                    }

                    if (!indexDatabases.Any(x => x.Equals(strategyDatabase)))
                    {
                        output.Error(GetErrorMessage(indexName, string.Join(", ", indexDatabases), strategy.Name, strategyDatabase));
                    }
                }
            }
        }
 public override void Process(ISolutionResourceContext data, ITestOutputContext output)
 {
     // ReSharper disable once AssignNullToNotNullAttribute
     output.Debug("ApplicationInfo: " + data.System.ApplicationInfo);
 }
        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);
                    }
                }
            }
        }
Beispiel #12
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);
            }
        }