/// <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)); }
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)); } } }
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); } }
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())); }
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); } } } }
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); } }