diff --git a/src/SIM.Sitecore9Installer.Tests/SIM.Sitecore9Installer.Tests.csproj b/src/SIM.Sitecore9Installer.Tests/SIM.Sitecore9Installer.Tests.csproj index 6fe2b325..7a920692 100644 --- a/src/SIM.Sitecore9Installer.Tests/SIM.Sitecore9Installer.Tests.csproj +++ b/src/SIM.Sitecore9Installer.Tests/SIM.Sitecore9Installer.Tests.csproj @@ -92,6 +92,7 @@ + diff --git a/src/SIM.Sitecore9Installer.Tests/Validation/Validators/PrerequisitesDownloadLinksValidatorTests.cs b/src/SIM.Sitecore9Installer.Tests/Validation/Validators/PrerequisitesDownloadLinksValidatorTests.cs new file mode 100644 index 00000000..ce2420a9 --- /dev/null +++ b/src/SIM.Sitecore9Installer.Tests/Validation/Validators/PrerequisitesDownloadLinksValidatorTests.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Linq; +using AutoFixture; +using NSubstitute; +using SIM.Sitecore9Installer.Tasks; +using SIM.Sitecore9Installer.Validation; +using SIM.Sitecore9Installer.Validation.Validators; +using Xunit; + +namespace SIM.Sitecore9Installer.Tests.Validation.Validators +{ + public class PrerequisitesDownloadLinksValidatorTests + { + private const string KnownIssueMessage = "{0}: the '{1}' parameter contains the following link that is not accessible:\n\n{2}\n\nThis behavior looks to be related to the following known issue:\n\n{3}\n\nPlease try to apply the solution mentioned there."; + + private const string InvalidLinkMessage = "{0}: the '{1}' parameter contains the following link that is not accessible:\n\n{2}\n\nPlease check the Internet connection and the link accessibility in a browser.\n\nThis behavior may also occur due to similar symptoms described in the following known issue:\n\n{3}"; + + private const string InvalidValueMessage = "{0}: the '{1}' parameter contains the following invalid value:\n\n{2}\n\nIt should contain download link that starts with '{3}'."; + + [Theory] + [InlineData("Prerequisites", "WebPlatformDownload", "https://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi", 1, KnownIssueMessage)] + [InlineData("Global", "WebPlatformDownload", "https://download.microsoft.com/download/C/F/F/CFF3A0B8-99D4-41A2-AE1A-496C08BEB904/WebPlatformInstaller_amd64_en-US.msi", 0, "")] + [InlineData("Prerequisites", "SQLODBCDriversx64", "https://download.microsoft.com/download/D/5/E/D5EEF288-A277-45C8-855B-8E2CB7E25B96/x64/msodbcsql.msi", 0, "")] + [InlineData("Prerequisites", "SQLODBCDriversx64", "https://download.microsoft.com/download/test", 1, InvalidLinkMessage)] + [InlineData("Prerequisites", "SQLODBCDriversx64", "test", 0, "")] + [InlineData("Prerequisites", "DotNetHostingDownload", "https://download.microsoft.com/download/6/E/B/6EBD972D-2E2F-41EB-9668-F73F5FDDC09C/dotnet-hosting-2.1.3-win.exe", 0, "")] + [InlineData("Prerequisites", "DotNetHostingDownload", "test", 1, InvalidValueMessage)] + public void EvaluateTests(string taskName, string paramName, string paramValue, int warningsCount, string message) + { + // Arrange + var fixture = new Fixture(); + GlobalParameters globals = new GlobalParameters(); + Task prerequisitesTask = Substitute.For(taskName, fixture.Create(), null, null, new Dictionary()); + InstallParam downloadLinkParam = new InstallParam(paramName, paramValue, false, InstallParamType.String); + List paramList = new List + { + downloadLinkParam + }; + LocalParameters locals = new LocalParameters(paramList, globals); + prerequisitesTask.LocalParams.Returns(locals); + + PrerequisitesDownloadLinksValidator validator = Substitute.ForPartsOf(); + validator.Data["ParamNamePostfix"] = "Download"; + validator.Data["ParamValuePrefixes"] = "http://|https://"; + List paramValuePrefixes = validator.Data["ParamValuePrefixes"].Split('|').ToList(); + + // Act + IEnumerable result = validator.Evaluate(new Task[] {prerequisitesTask}); + IEnumerable warnings = result.Where(r => r.State == ValidatorState.Warning); + + // Assert + Assert.Equal(warnings.Count(), warningsCount); + if (message == KnownIssueMessage || message == InvalidLinkMessage) + { + this.ValidateMessage(warnings, message, taskName, paramName, paramValue, validator.KnownIssueLink); + } + else + { + this.ValidateMessage(warnings, message, taskName, paramName, paramValue, string.Join("' or '", paramValuePrefixes)); + } + } + + private void ValidateMessage(IEnumerable warnings, string message, string taskName, string paramName, string paramValue, string paramChangeable) + { + if (!string.IsNullOrEmpty(message)) + { + message = string.Format(message, taskName, paramName, paramValue, paramChangeable); + Assert.Contains(warnings, warning => warning.Message.Equals(message)); + } + } + } +} \ No newline at end of file diff --git a/src/SIM.Sitecore9Installer/SIM.Sitecore9Installer.csproj b/src/SIM.Sitecore9Installer/SIM.Sitecore9Installer.csproj index fe94c8b8..dcb2a967 100644 --- a/src/SIM.Sitecore9Installer/SIM.Sitecore9Installer.csproj +++ b/src/SIM.Sitecore9Installer/SIM.Sitecore9Installer.csproj @@ -128,6 +128,7 @@ + diff --git a/src/SIM.Sitecore9Installer/Validation/Validators/PrerequisitesDownloadLinksValidator.cs b/src/SIM.Sitecore9Installer/Validation/Validators/PrerequisitesDownloadLinksValidator.cs new file mode 100644 index 00000000..b6b87e87 --- /dev/null +++ b/src/SIM.Sitecore9Installer/Validation/Validators/PrerequisitesDownloadLinksValidator.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using SIM.Sitecore9Installer.Tasks; + +namespace SIM.Sitecore9Installer.Validation.Validators +{ + public class PrerequisitesDownloadLinksValidator : BaseValidator + { + public override string SuccessMessage => "Prerequisites download links are valid."; + + protected virtual string TaskName => "Prerequisites"; + + // parameter to validate the following known issue: https://github.com/Sitecore/Sitecore-Instance-Manager/wiki/Known-Issue-Outdated-Download-Link-to-Microsoft-Web-Platform-Installer + public virtual string WebPlatformDownload => "WebPlatformDownload"; + + public virtual string KnownIssueLink => "https://github.com/Sitecore/Sitecore-Instance-Manager/wiki/Known-Issue-Outdated-Download-Link-to-Microsoft-Web-Platform-Installer"; + + protected override IEnumerable GetErrorsForTask(Task task, IEnumerable paramsToValidate) + { + string paramNamePostfix = string.Empty; + if (this.Data.ContainsKey("ParamNamePostfix")) + { + paramNamePostfix = this.Data["ParamNamePostfix"]; + } + + List paramValuePrefixes = new List(); + if (this.Data.ContainsKey("ParamValuePrefixes")) + { + paramValuePrefixes = this.Data["ParamValuePrefixes"].Split('|').ToList(); + } + + if (!string.IsNullOrEmpty(paramNamePostfix) && paramValuePrefixes.Count > 0) + { + if (task.Name.Equals(TaskName, StringComparison.InvariantCultureIgnoreCase)) + { + foreach (InstallParam installParam in paramsToValidate) + { + if (paramValuePrefixes.Any(paramValuePrefix => installParam.Value.StartsWith(paramValuePrefix, StringComparison.InvariantCultureIgnoreCase))) + { + if (!this.IsDownloadLinkValid(installParam.Value)) + { + if (installParam.Name == this.WebPlatformDownload) + { + yield return new ValidationResult(ValidatorState.Warning, + $"{TaskName}: the '{installParam.Name}' parameter contains the following link that is not accessible:\n\n{installParam.Value}\n\nThis behavior looks to be related to the following known issue:\n\n{KnownIssueLink}\n\nPlease try to apply the solution mentioned there.", + null); + } + else + { + yield return new ValidationResult(ValidatorState.Warning, + $"{TaskName}: the '{installParam.Name}' parameter contains the following link that is not accessible:\n\n{installParam.Value}\n\nPlease check the Internet connection and the link accessibility in a browser.\n\nThis behavior may also occur due to similar symptoms described in the following known issue:\n\n{KnownIssueLink}", + null); + } + } + } + else if (installParam.Name.EndsWith(paramNamePostfix, StringComparison.InvariantCultureIgnoreCase)) + { + yield return new ValidationResult(ValidatorState.Warning, + $"{TaskName}: the '{installParam.Name}' parameter contains the following invalid value:\n\n{installParam.Value}\n\nIt should contain download link that starts with '{string.Join("' or '", paramValuePrefixes)}'.", + null); + } + } + } + } + } + + private bool IsDownloadLinkValid(string link) + { + using (HttpClient authClient = new HttpClient()) + { + try + { + var response = authClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, new Uri(link))).Result; + if (response.IsSuccessStatusCode) + { + return true; + } + } + catch + { + return false; + } + } + + return false; + } + } +} \ No newline at end of file diff --git a/src/SIM.Tool/GlobalParamsConfig/Validators.json b/src/SIM.Tool/GlobalParamsConfig/Validators.json index d8fa99f2..a948f324 100644 --- a/src/SIM.Tool/GlobalParamsConfig/Validators.json +++ b/src/SIM.Tool/GlobalParamsConfig/Validators.json @@ -202,6 +202,14 @@ "Data": { "LicenseFileVariable": "LicenseFile" } + }, + { + "Name": "PrerequisitesDownloadLinksValidator", + "Type": "SIM.Sitecore9Installer.Validation.Validators.PrerequisitesDownloadLinksValidator", + "Data": { + "ParamNamePostfix": "Download", + "ParamValuePrefixes": "http://|https://" + } } ], "ValidatorLists": { @@ -241,22 +249,26 @@ "Sitecore_9.1": [ "9.1_SqlCompatibilityValidator", "9.1_SolrVersionValidator", - "CmIdentityServerSiteNameValidator" + "CmIdentityServerSiteNameValidator", + "PrerequisitesDownloadLinksValidator" ], "Sitecore_9.2": [ "9.2_SqlCompatibilityValidator", "9.2_SolrVersionValidator", - "CmIdentityServerSiteNameValidator" + "CmIdentityServerSiteNameValidator", + "PrerequisitesDownloadLinksValidator" ], "Sitecore_9.3": [ "9.3_SqlCompatibilityValidator", "9.3_SolrVersionValidator", - "CmIdentityServerSiteNameValidator" + "CmIdentityServerSiteNameValidator", + "PrerequisitesDownloadLinksValidator" ], "Sitecore_10.0": [ "9.3_SqlCompatibilityValidator", "10.0_SolrVersionValidator", - "CmIdentityServerSiteNameValidator" + "CmIdentityServerSiteNameValidator", + "PrerequisitesDownloadLinksValidator" ] } }