From 221adfc6bff6898bfe4b51f6c58b05ad3828ce10 Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 12:44:52 +0200 Subject: [PATCH 1/6] Fix hash file caching The hash file was never cached and always downloaded again Fixes #2365 --- .../DownloadStrategies/CacheDownloadStrategy.cs | 16 ++++++++++++---- .../DownloadStrategies/DownloadStrategy.cs | 6 +++--- .../DownloadStrategies/GitHubDownloadStrategy.cs | 4 +++- .../DownloadStrategies/IDownloadStrategy.cs | 2 +- .../DownloadStrategies/NugetDownloadStrategy.cs | 3 ++- .../TemporarilyIgnoreUpdatesDownloadStrategy.cs | 4 ++-- src/Paket.Bootstrapper/Paket.Bootstrapper.csproj | 1 + 7 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs index b3a095bfcc..46b952f301 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs @@ -71,16 +71,19 @@ protected override void DownloadVersionCore(string latestVersion, string target) } } - protected override void DownloadHashFileCore(string latestVersion) + protected override string DownloadHashFileCore(string latestVersion) { - var cached = Path.Combine(_paketCacheDir, latestVersion, "paket-sha256.txt"); + var cached = GetHashFilePathInCache(latestVersion); if (!FileSystemProxy.FileExists(cached)) { ConsoleImpl.WriteInfo("Hash file of version {0} not found in cache.", latestVersion); - EffectiveStrategy.DownloadHashFile(latestVersion); + var effectivePath = EffectiveStrategy.DownloadHashFile(latestVersion); + FileSystemProxy.CopyFile(effectivePath, cached, true); } + + return cached; } protected override void SelfUpdateCore(string latestVersion) @@ -116,7 +119,7 @@ private string GetLatestVersionInCache(bool ignorePrerelease) private bool ValidateHash(string version, string paketFile) { - var hashFile = Path.Combine(_paketCacheDir, version, "paket-sha256.txt"); + var hashFile = GetHashFilePathInCache(version); if (!FileSystemProxy.FileExists(hashFile)) { @@ -146,5 +149,10 @@ private bool ValidateHash(string version, string paketFile) return string.Equals(expectedHash, hash, StringComparison.OrdinalIgnoreCase); } } + + private string GetHashFilePathInCache(string version) + { + return Path.Combine(_paketCacheDir, version, "paket-sha256.txt"); + } } } \ No newline at end of file diff --git a/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs index 9dc52a10ce..f7f96039c3 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs @@ -24,15 +24,15 @@ public void SelfUpdate(string latestVersion) Wrap(() => SelfUpdateCore(latestVersion), "SelfUpdate"); } - public void DownloadHashFile(string latestVersion) + public string DownloadHashFile(string latestVersion) { - Wrap(() => DownloadHashFileCore(latestVersion), "DownloadHashFile"); + return Wrap(() => DownloadHashFileCore(latestVersion), "DownloadHashFile"); } protected abstract string GetLatestVersionCore(bool ignorePrerelease); protected abstract void DownloadVersionCore(string latestVersion, string target); protected abstract void SelfUpdateCore(string latestVersion); - protected abstract void DownloadHashFileCore(string latestVersion); + protected abstract string DownloadHashFileCore(string latestVersion); private void Wrap(Action action, string actionName) { diff --git a/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs index 91fb60aefe..72ffb467b7 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs @@ -114,13 +114,15 @@ protected override void SelfUpdateCore(string latestVersion) } } - protected override void DownloadHashFileCore(string latestVersion) + protected override string DownloadHashFileCore(string latestVersion) { var url = String.Format(Constants.PaketCheckSumDownloadUrlTemplate, latestVersion); ConsoleImpl.WriteInfo("Starting download from {0}", url); var tmpFile = BootstrapperHelper.GetTempFile("paket-sha256.txt"); WebRequestProxy.DownloadFile(url, tmpFile); + + return tmpFile; } } } \ No newline at end of file diff --git a/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs index 0a53b3b5bd..dc8734f1e0 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs @@ -7,6 +7,6 @@ public interface IDownloadStrategy string GetLatestVersion(bool ignorePrerelease); void DownloadVersion(string latestVersion, string target); void SelfUpdate(string latestVersion); - void DownloadHashFile(string latestVersion); + string DownloadHashFile(string latestVersion); } } \ No newline at end of file diff --git a/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs index aa4b2c618f..290585810b 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs @@ -226,9 +226,10 @@ protected override void SelfUpdateCore(string latestVersion) FileSystemProxy.DeleteDirectory(randomFullPath, true); } - protected override void DownloadHashFileCore(string latestVersion) + protected override string DownloadHashFileCore(string latestVersion) { // TODO: implement get hash file + return null; } } } \ No newline at end of file diff --git a/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs index 300cd0baeb..bb526e6caa 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs @@ -118,9 +118,9 @@ private void TouchTarget(string target) } } - protected override void DownloadHashFileCore(string latestVersion) + protected override string DownloadHashFileCore(string latestVersion) { - _effectiveStrategy.DownloadHashFile(latestVersion); + return _effectiveStrategy.DownloadHashFile(latestVersion); } } } diff --git a/src/Paket.Bootstrapper/Paket.Bootstrapper.csproj b/src/Paket.Bootstrapper/Paket.Bootstrapper.csproj index 20ec43fd81..2fe1eec602 100644 --- a/src/Paket.Bootstrapper/Paket.Bootstrapper.csproj +++ b/src/Paket.Bootstrapper/Paket.Bootstrapper.csproj @@ -23,6 +23,7 @@ prompt 4 false + 5 AnyCPU From c3609f5249413f7b50e6986fd71a0ec49a2b6357 Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 13:21:32 +0200 Subject: [PATCH 2/6] Better logs when checking hashes --- .../CacheDownloadStrategy.cs | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs index 46b952f301..ab95d308ef 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs @@ -53,21 +53,38 @@ protected override void DownloadVersionCore(string latestVersion, string target) { var cached = Path.Combine(_paketCacheDir, latestVersion, "paket.exe"); - if (!FileSystemProxy.FileExists(cached) || !ValidateHash(latestVersion, cached)) + if (!FileSystemProxy.FileExists(cached)) { ConsoleImpl.WriteInfo("Version {0} not found in cache.", latestVersion); - EffectiveStrategy.DownloadVersion(latestVersion, target); + DownloadAndPlaceInCache(latestVersion, target, cached); + return; + } + + if (!ValidateHash(latestVersion, cached)) + { + ConsoleImpl.WriteWarning("Version {0} found in cache but it's hash isn't valid.", latestVersion); - ConsoleImpl.WriteTrace("Caching version {0} for later", latestVersion); - FileSystemProxy.CreateDirectory(Path.GetDirectoryName(cached)); - FileSystemProxy.CopyFile(target, cached); + DownloadAndPlaceInCache(latestVersion, target, cached); + return; } - else + + ConsoleImpl.WriteInfo("Copying version {0} from cache.", latestVersion); + ConsoleImpl.WriteTrace("{0} -> {1}", cached, target); + FileSystemProxy.CopyFile(cached, target, true); + } + + private void DownloadAndPlaceInCache(string latestVersion, string target, string cached) + { + EffectiveStrategy.DownloadVersion(latestVersion, target); + + ConsoleImpl.WriteTrace("Caching version {0} for later", latestVersion); + FileSystemProxy.CreateDirectory(Path.GetDirectoryName(cached)); + FileSystemProxy.CopyFile(target, cached); + + if (!ValidateHash(latestVersion, cached)) { - ConsoleImpl.WriteInfo("Copying version {0} from cache.", latestVersion); - ConsoleImpl.WriteTrace("{0} -> {1}", cached, target); - FileSystemProxy.CopyFile(cached, target, true); + ConsoleImpl.WriteWarning("Hash of downloaded paket.exe is invalid"); } } @@ -78,8 +95,10 @@ protected override string DownloadHashFileCore(string latestVersion) if (!FileSystemProxy.FileExists(cached)) { ConsoleImpl.WriteInfo("Hash file of version {0} not found in cache.", latestVersion); - var effectivePath = EffectiveStrategy.DownloadHashFile(latestVersion); + + ConsoleImpl.WriteTrace("Copying hash file in cache."); + ConsoleImpl.WriteTrace("{0} -> {1}", effectivePath, cached); FileSystemProxy.CopyFile(effectivePath, cached, true); } @@ -141,7 +160,7 @@ private bool ValidateHash(string version, string paketFile) } using (var stream = FileSystemProxy.OpenRead(paketFile)) - using (var sha = new SHA256Managed()) + using (var sha = SHA256.Create()) { byte[] checksum = sha.ComputeHash(stream); var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); From e961880800fb3dd4b80ab3a89e9e6093ba51edb4 Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 13:53:29 +0200 Subject: [PATCH 3/6] Make hash file checking a top-level operation --- src/Paket.Bootstrapper/BootstrapperHelper.cs | 39 +++++++++++ .../CacheDownloadStrategy.cs | 65 ++++++------------- .../DownloadStrategies/DownloadStrategy.cs | 10 +-- .../GitHubDownloadStrategy.cs | 27 +++++++- .../DownloadStrategies/IDownloadStrategy.cs | 3 +- .../NugetDownloadStrategy.cs | 7 +- ...emporarilyIgnoreUpdatesDownloadStrategy.cs | 9 ++- src/Paket.Bootstrapper/Program.cs | 13 +++- 8 files changed, 118 insertions(+), 55 deletions(-) diff --git a/src/Paket.Bootstrapper/BootstrapperHelper.cs b/src/Paket.Bootstrapper/BootstrapperHelper.cs index 6697ebe628..b33ccf28e9 100644 --- a/src/Paket.Bootstrapper/BootstrapperHelper.cs +++ b/src/Paket.Bootstrapper/BootstrapperHelper.cs @@ -3,6 +3,8 @@ using System.Net; using System.Linq; using System.Reflection; +using System.Security.Cryptography; +using Paket.Bootstrapper.HelperProxies; namespace Paket.Bootstrapper { @@ -103,5 +105,42 @@ internal static void FileMove(string oldPath, string newPath) File.Move(oldPath, newPath); } + + public static bool ValidateHash(IFileSystemProxy fileSystem, string hashFile, string version, string paketFile) + { + if (hashFile == null) + { + ConsoleImpl.WriteTrace("No hash file expected, bypassing check."); + return true; + } + + if (!fileSystem.FileExists(hashFile)) + { + ConsoleImpl.WriteInfo("No hash file of version {0} found.", version); + + return true; + } + + var dict = fileSystem.ReadAllLines(hashFile) + .Select(i => i.Split(' ')) + .ToDictionary(i => i[1], i => i[0]); + + string expectedHash; + if (!dict.TryGetValue("paket.exe", out expectedHash)) + { + fileSystem.DeleteFile(hashFile); + + throw new InvalidDataException("Paket hash file is corrupted"); + } + + using (var stream = fileSystem.OpenRead(paketFile)) + using (var sha = SHA256.Create()) + { + byte[] checksum = sha.ComputeHash(stream); + var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); + + return string.Equals(expectedHash, hash, StringComparison.OrdinalIgnoreCase); + } + } } } diff --git a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs index ab95d308ef..40df75780f 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs @@ -11,6 +11,11 @@ internal class CacheDownloadStrategy : DownloadStrategy, IHaveEffectiveStrategy { public override string Name { get { return String.Format("{0} - cached", EffectiveStrategy.Name); } } + public override bool CanDownloadHashFile + { + get { return EffectiveStrategy.CanDownloadHashFile; } + } + private readonly string _paketCacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "NuGet", "Cache", "Paket"); @@ -49,7 +54,7 @@ protected override string GetLatestVersionCore(bool ignorePrerelease) } } - protected override void DownloadVersionCore(string latestVersion, string target) + protected override void DownloadVersionCore(string latestVersion, string target, string hashfile) { var cached = Path.Combine(_paketCacheDir, latestVersion, "paket.exe"); @@ -57,15 +62,15 @@ protected override void DownloadVersionCore(string latestVersion, string target) { ConsoleImpl.WriteInfo("Version {0} not found in cache.", latestVersion); - DownloadAndPlaceInCache(latestVersion, target, cached); + DownloadAndPlaceInCache(latestVersion, target, cached, hashfile); return; } - if (!ValidateHash(latestVersion, cached)) + if (!BootstrapperHelper.ValidateHash(FileSystemProxy, hashfile, latestVersion, cached)) { ConsoleImpl.WriteWarning("Version {0} found in cache but it's hash isn't valid.", latestVersion); - DownloadAndPlaceInCache(latestVersion, target, cached); + DownloadAndPlaceInCache(latestVersion, target, cached, hashfile); return; } @@ -74,28 +79,33 @@ protected override void DownloadVersionCore(string latestVersion, string target) FileSystemProxy.CopyFile(cached, target, true); } - private void DownloadAndPlaceInCache(string latestVersion, string target, string cached) + private void DownloadAndPlaceInCache(string latestVersion, string target, string cached, string hashfile) { - EffectiveStrategy.DownloadVersion(latestVersion, target); + EffectiveStrategy.DownloadVersion(latestVersion, target, hashfile); ConsoleImpl.WriteTrace("Caching version {0} for later", latestVersion); FileSystemProxy.CreateDirectory(Path.GetDirectoryName(cached)); FileSystemProxy.CopyFile(target, cached); - - if (!ValidateHash(latestVersion, cached)) - { - ConsoleImpl.WriteWarning("Hash of downloaded paket.exe is invalid"); - } } protected override string DownloadHashFileCore(string latestVersion) { + if (!EffectiveStrategy.CanDownloadHashFile) + { + return null; + } + var cached = GetHashFilePathInCache(latestVersion); if (!FileSystemProxy.FileExists(cached)) { ConsoleImpl.WriteInfo("Hash file of version {0} not found in cache.", latestVersion); var effectivePath = EffectiveStrategy.DownloadHashFile(latestVersion); + if(effectivePath == null) + { + // 'EffectiveStrategy.CanDownloadHashFile' should have returned false... + return null; + } ConsoleImpl.WriteTrace("Copying hash file in cache."); ConsoleImpl.WriteTrace("{0} -> {1}", effectivePath, cached); @@ -136,39 +146,6 @@ private string GetLatestVersionInCache(bool ignorePrerelease) .FirstOrDefault() ?? "0"; } - private bool ValidateHash(string version, string paketFile) - { - var hashFile = GetHashFilePathInCache(version); - - if (!FileSystemProxy.FileExists(hashFile)) - { - ConsoleImpl.WriteInfo("No hash file of version {0} found in cache.", version); - - return true; - } - - var dict = FileSystemProxy.ReadAllLines(hashFile) - .Select(i => i.Split(' ')) - .ToDictionary(i => i[1], i => i[0]); - - string expectedHash; - if (!dict.TryGetValue("paket.exe", out expectedHash)) - { - FileSystemProxy.DeleteFile(hashFile); - - throw new InvalidDataException("Paket hash file is corrupted"); - } - - using (var stream = FileSystemProxy.OpenRead(paketFile)) - using (var sha = SHA256.Create()) - { - byte[] checksum = sha.ComputeHash(stream); - var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); - - return string.Equals(expectedHash, hash, StringComparison.OrdinalIgnoreCase); - } - } - private string GetHashFilePathInCache(string version) { return Path.Combine(_paketCacheDir, version, "paket-sha256.txt"); diff --git a/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs index f7f96039c3..ab02b77ea0 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/DownloadStrategy.cs @@ -6,17 +6,17 @@ namespace Paket.Bootstrapper.DownloadStrategies public abstract class DownloadStrategy : IDownloadStrategy { public abstract string Name { get; } + public abstract bool CanDownloadHashFile { get; } + public IDownloadStrategy FallbackStrategy { get; set; } public string GetLatestVersion(bool ignorePrerelease) { return Wrap(() => GetLatestVersionCore(ignorePrerelease), "GetLatestVersion"); } - public void DownloadVersion(string latestVersion, string target) + public void DownloadVersion(string latestVersion, string target, string hashfile) { - DownloadHashFile(latestVersion); - - Wrap(() => DownloadVersionCore(latestVersion, target), "DownloadVersion"); + Wrap(() => DownloadVersionCore(latestVersion, target, hashfile), "DownloadVersion"); } public void SelfUpdate(string latestVersion) @@ -30,7 +30,7 @@ public string DownloadHashFile(string latestVersion) } protected abstract string GetLatestVersionCore(bool ignorePrerelease); - protected abstract void DownloadVersionCore(string latestVersion, string target); + protected abstract void DownloadVersionCore(string latestVersion, string target, string hashfile); protected abstract void SelfUpdateCore(string latestVersion); protected abstract string DownloadHashFileCore(string latestVersion); diff --git a/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs index 72ffb467b7..bcc20f4b06 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/GitHubDownloadStrategy.cs @@ -20,6 +20,11 @@ public static class Constants private IFileSystemProxy FileSystemProxy { get; set; } public override string Name { get { return "Github"; } } + public override bool CanDownloadHashFile + { + get { return true; } + } + public GitHubDownloadStrategy(IWebRequestProxy webRequestProxy, IFileSystemProxy fileSystemProxy) { WebRequestProxy = webRequestProxy; @@ -70,7 +75,7 @@ private List GetVersions(string data) return versions; } - protected override void DownloadVersionCore(string latestVersion, string target) + protected override void DownloadVersionCore(string latestVersion, string target, string hashfile) { var url = String.Format(Constants.PaketExeDownloadUrlTemplate, latestVersion); ConsoleImpl.WriteInfo("Starting download from {0}", url); @@ -78,6 +83,26 @@ protected override void DownloadVersionCore(string latestVersion, string target) var tmpFile = BootstrapperHelper.GetTempFile("paket"); WebRequestProxy.DownloadFile(url, tmpFile); + if (!BootstrapperHelper.ValidateHash(FileSystemProxy, hashfile, latestVersion, tmpFile)) + { + ConsoleImpl.WriteWarning("Hash of downloaded paket.exe is invalid, retrying once"); + + WebRequestProxy.DownloadFile(url, tmpFile); + + if (!BootstrapperHelper.ValidateHash(FileSystemProxy, hashfile, latestVersion, tmpFile)) + { + ConsoleImpl.WriteWarning("Hash of downloaded paket.exe still invalid (Using the file anyway)"); + } + else + { + ConsoleImpl.WriteTrace("Hash of downloaded file successfully found in {0}", hashfile); + } + } + else + { + ConsoleImpl.WriteTrace("Hash of downloaded file successfully found in {0}", hashfile); + } + FileSystemProxy.CopyFile(tmpFile, target, true); FileSystemProxy.DeleteFile(tmpFile); } diff --git a/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs index dc8734f1e0..c62250589c 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/IDownloadStrategy.cs @@ -5,8 +5,9 @@ public interface IDownloadStrategy string Name { get; } IDownloadStrategy FallbackStrategy { get; set; } string GetLatestVersion(bool ignorePrerelease); - void DownloadVersion(string latestVersion, string target); + void DownloadVersion(string latestVersion, string target, string hashFile); void SelfUpdate(string latestVersion); string DownloadHashFile(string latestVersion); + bool CanDownloadHashFile { get; } } } \ No newline at end of file diff --git a/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs index 290585810b..ca8bdd41a5 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/NugetDownloadStrategy.cs @@ -68,6 +68,11 @@ public override string Name get { return "Nuget"; } } + public override bool CanDownloadHashFile + { + get { return false; } + } + protected override string GetLatestVersionCore(bool ignorePrerelease) { IEnumerable allVersions = null; @@ -100,7 +105,7 @@ protected override string GetLatestVersionCore(bool ignorePrerelease) return latestVersion != null ? latestVersion.Original : String.Empty; } - protected override void DownloadVersionCore(string latestVersion, string target) + protected override void DownloadVersionCore(string latestVersion, string target, string hashfile) { var apiHelper = new NugetApiHelper(PaketNugetPackageName, NugetSource); diff --git a/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs index bb526e6caa..fa73b3e440 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategy.cs @@ -59,9 +59,9 @@ protected override string GetLatestVersionCore(bool ignorePrerelease) return latestVersion; } - protected override void DownloadVersionCore(string latestVersion, string target) + protected override void DownloadVersionCore(string latestVersion, string target, string hashfile) { - _effectiveStrategy.DownloadVersion(latestVersion, target); + _effectiveStrategy.DownloadVersion(latestVersion, target, hashfile); TouchTarget(target); } @@ -72,6 +72,11 @@ protected override void SelfUpdateCore(string latestVersion) public override string Name { get { return string.Format("{0} (temporarily ignore updates)", EffectiveStrategy.Name); } } + public override bool CanDownloadHashFile + { + get { return EffectiveStrategy.CanDownloadHashFile; } + } + public IDownloadStrategy EffectiveStrategy { get { return _effectiveStrategy; } set { diff --git a/src/Paket.Bootstrapper/Program.cs b/src/Paket.Bootstrapper/Program.cs index 8393f07566..527ea6a61f 100644 --- a/src/Paket.Bootstrapper/Program.cs +++ b/src/Paket.Bootstrapper/Program.cs @@ -130,10 +130,21 @@ public static void StartPaketBootstrapping(IDownloadStrategy downloadStrategy, D if ((comparison > 0 && specificVersionRequested) || comparison < 0) { + string hashFile = null; + if (downloadStrategy.CanDownloadHashFile) + { + ConsoleImpl.WriteTrace("Downloading hash for v{0} ...", latestVersion); + var downloadHashWatch = Stopwatch.StartNew(); + hashFile = downloadStrategy.DownloadHashFile(latestVersion); + downloadHashWatch.Stop(); + + ConsoleImpl.WriteTrace("Hash download took {0:0.##} second(s)", downloadHashWatch.Elapsed.TotalSeconds); + } + ConsoleImpl.WriteTrace("Downloading v{0} ...", latestVersion); var downloadWatch = Stopwatch.StartNew(); - downloadStrategy.DownloadVersion(latestVersion, dlArgs.Target); + downloadStrategy.DownloadVersion(latestVersion, dlArgs.Target, hashFile); downloadWatch.Stop(); ConsoleImpl.WriteTrace("Download took {0:0.##} second(s)", downloadWatch.Elapsed.TotalSeconds); From 2aecab12c6c1d26188decc8829bedb0536dfa3a3 Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 14:47:04 +0200 Subject: [PATCH 4/6] Fix tests build --- .../CacheDownloadStrategyTest.cs | 20 +++++++++---------- .../GitHubDownloadStrategyTest.cs | 2 +- .../NugetDownloadStrategyTests.cs | 8 ++++---- ...rarilyIgnoreUpdatesDownloadStrategyTest.cs | 4 ++-- .../StartPaketBootstrappingTests.cs | 16 +++++++-------- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs index 7c32275e69..b0664e4f0e 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs @@ -135,10 +135,10 @@ public void DownloadVersion_UseCachedVersion() mockFileProxy.Setup(x => x.FileExists(ItHasFilename("paket.exe"))).Returns(true); //act - sut.DownloadVersion("any", "any"); + sut.DownloadVersion("any", "any", null); //assert - mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Never); + mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); mockFileProxy.Verify(x => x.CopyFile(It.IsAny(), It.IsAny(), It.IsAny())); } @@ -149,10 +149,10 @@ public void DownloadVersion_DownloadFromFallback() mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(false); //act - sut.DownloadVersion("any", "any"); + sut.DownloadVersion("any", "any", null); //assert - mockEffectiveStrategy.Verify(x => x.DownloadVersion("any", "any")); + mockEffectiveStrategy.Verify(x => x.DownloadVersion("any", "any", null)); mockFileProxy.Verify(x => x.CopyFile(It.IsAny(), It.IsAny(), It.IsAny())); } @@ -177,10 +177,10 @@ public void GetLatestVersion_PaketFileCorrupt_DownloadPaketFile() mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - sut.DownloadVersion("any", "any"); + sut.DownloadVersion("any", "any", null); //assert - mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Once); + mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); mockFileProxy.Verify(x => x.CopyFile(It.IsAny(), It.IsAny(), It.IsAny())); } @@ -198,10 +198,10 @@ public void GetLatestVersion_PaketFileNotCorrupt_DontDownloadPaketFile() mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - sut.DownloadVersion("any", "any"); + sut.DownloadVersion("any", "any", null); //assert - mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Never); + mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); mockFileProxy.Verify(x => x.CopyFile(It.IsAny(), It.IsAny(), It.IsAny())); } @@ -215,10 +215,10 @@ public void GetLatestVersion_PaketHashFileExistsButIsCorrupt_DeleteHashFileAndTh mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - Assert.Throws(() => sut.DownloadVersion("any", "any")); + Assert.Throws(() => sut.DownloadVersion("any", "any", null)); //assert - mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Never); + mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); mockFileProxy.Verify(x => x.DeleteFile(ItHasFilename("paket-sha256.txt"))); } diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs index be5952ee17..c72a7e15fc 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs @@ -60,7 +60,7 @@ public void DownloadVersion() mockWebProxy.Setup(x => x.DownloadFile(It.IsAny(), It.IsAny())).Verifiable(); //act - sut.DownloadVersion("2.57.1", "paketExeLocation"); + sut.DownloadVersion("2.57.1", "paketExeLocation", null); //assert mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName)); diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs index 5248142611..97f1ed87eb 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs @@ -97,7 +97,7 @@ public void DefaultApi_DownloadVersion() CreateSystemUnderTestWithDefaultApi(); //act - sut.DownloadVersion(null, "paket"); + sut.DownloadVersion(null, "paket", null); //assert mockWebRequestProxy.Verify(x => x.DownloadFile("https://www.nuget.org/api/v2/package/Paket", It.IsAny())); @@ -113,7 +113,7 @@ public void DefaultApi_DownloadSpecificVersion() CreateSystemUnderTestWithDefaultApi(); //act - sut.DownloadVersion("2.57.0", "paket"); + sut.DownloadVersion("2.57.0", "paket", null); //assert mockWebRequestProxy.Verify(x => x.DownloadFile("https://www.nuget.org/api/v2/package/Paket/2.57.0", It.IsAny())); @@ -241,7 +241,7 @@ public void NugetFolder_DownloadVersion_NoVersionSpecified_GetsLatestVersion() .Returns(new[] { "paket.111.nupkg" }); //act - sut.DownloadVersion(null, "paket"); + sut.DownloadVersion(null, "paket", null); //assert mockFileProxy.Verify(x => x.CopyFile(It.Is(s => s.StartsWith("anyNugetFolder") && s.EndsWith("paket.111.nupkg")), It.Is(s => s.StartsWith("folder") && s.EndsWith("paket.latest.nupkg")), false)); @@ -258,7 +258,7 @@ public void NugetFolder_DownloadSpecificVersion() CreateSystemUnderTestWithNugetFolder(); //act - sut.DownloadVersion("2.57.0", "paket"); + sut.DownloadVersion("2.57.0", "paket", null); //assert mockFileProxy.Verify(x => x.CopyFile(It.Is(s => s.StartsWith("anyNugetFolder") && s.EndsWith("paket.2.57.0.nupkg")), It.Is(s => s.StartsWith("folder") && s.EndsWith("paket.2.57.0.nupkg")), false)); diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs index 41ed3f7f66..f8c9a0edab 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs @@ -162,10 +162,10 @@ public void DownloadVersion_Touches_Target() { //arrange _mockFileProxy.Setup(fp => fp.Touch(Target)).Verifiable(); - _mockEffectiveStrategy.Setup(x => x.DownloadVersion("any", Target)).Verifiable(); + _mockEffectiveStrategy.Setup(x => x.DownloadVersion("any", Target, null)).Verifiable(); //act - _sut.DownloadVersion("any", Target); + _sut.DownloadVersion("any", Target, null); //assert _mockEffectiveStrategy.Verify(); diff --git a/tests/Paket.Bootstrapper.Tests/StartPaketBootstrappingTests.cs b/tests/Paket.Bootstrapper.Tests/StartPaketBootstrappingTests.cs index 760780cdde..435a9d5624 100644 --- a/tests/Paket.Bootstrapper.Tests/StartPaketBootstrappingTests.cs +++ b/tests/Paket.Bootstrapper.Tests/StartPaketBootstrappingTests.cs @@ -36,7 +36,7 @@ public void DownloadNewVersion_LocalVersionIsOutdated() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion("1.1", dlArgs.Target)); + mockDownloadStrategy.Verify(x => x.DownloadVersion("1.1", dlArgs.Target, null)); } [Test] @@ -51,7 +51,7 @@ public void DownloadSepcificVersion_IsUpgrade() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion("1.3", dlArgs.Target)); + mockDownloadStrategy.Verify(x => x.DownloadVersion("1.3", dlArgs.Target, null)); } [Test] @@ -66,7 +66,7 @@ public void DownloadSepcificVersion_IsDowngrade() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion("1.3", dlArgs.Target)); + mockDownloadStrategy.Verify(x => x.DownloadVersion("1.3", dlArgs.Target, null)); } [Test] @@ -81,7 +81,7 @@ public void DownloadNoNewVersion_LocalVersionIsCurrent() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Never); + mockDownloadStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); } [Test] @@ -96,7 +96,7 @@ public void DownloadCurrentVersion_LocalVersionIsPrerelease() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny()), Times.Once); + mockDownloadStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Once); } [Test] @@ -112,7 +112,7 @@ public void DownloadPrerelease_LocalVersionIsCurrent() //assert mockFileProxy.Verify(); - mockDownloadStrategy.Verify(x => x.DownloadVersion("1.1-alpha", dlArgs.Target)); + mockDownloadStrategy.Verify(x => x.DownloadVersion("1.1-alpha", dlArgs.Target, null)); } [Test] @@ -194,7 +194,7 @@ public void FirstStrategyFails_UseFallbackStrategy_FallbackStrategyWillBeUsed() //assert mockFileProxy.Verify(); - mockFallbackStrategy.Verify(x => x.DownloadVersion("1.2", dlArgs.Target)); + mockFallbackStrategy.Verify(x => x.DownloadVersion("1.2", dlArgs.Target, null)); } [Test] @@ -222,7 +222,7 @@ public void OnSuccess_NeverCalledWhenFail() Action onSuccess = () => successCount++; dlArgs.LatestVersion = "1.5"; mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(false); - mockDownloadStrategy.Setup(x => x.DownloadVersion("1.5", "paket.exe")).Throws(new WebException()); + mockDownloadStrategy.Setup(x => x.DownloadVersion("1.5", "paket.exe", null)).Throws(new WebException()); //act Program.StartPaketBootstrapping(mockDownloadStrategy.Object, dlArgs, mockFileProxy.Object, onSuccess); From 5bd581f96b2c02b19cd4020bf2fc29899b32eb8f Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 22:45:16 +0200 Subject: [PATCH 5/6] Fix cache strategy tests --- .../CacheDownloadStrategyTest.cs | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs index b0664e4f0e..0a2b49163a 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs @@ -170,14 +170,16 @@ public void SelfUpdate() [Test] public void GetLatestVersion_PaketFileCorrupt_DownloadPaketFile() { + const string hashFile = @"C:\hash.txt"; + //arrange mockEffectiveStrategy.Setup(x => x.GetLatestVersion(true)).Throws().Verifiable(); mockFileProxy.Setup(x => x.OpenRead(It.IsAny())).Returns(new MemoryStream(Guid.NewGuid().ToByteArray())); - mockFileProxy.Setup(x => x.ReadAllLines(It.IsAny())).Returns(new[] { Guid.NewGuid().ToString().Replace("-", String.Empty) + " paket.exe" }); + mockFileProxy.Setup(x => x.ReadAllLines(hashFile)).Returns(new[] { Guid.NewGuid().ToString().Replace("-", String.Empty) + " paket.exe" }); mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - sut.DownloadVersion("any", "any", null); + sut.DownloadVersion("any", "any", hashFile); //assert mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); @@ -187,6 +189,8 @@ public void GetLatestVersion_PaketFileCorrupt_DownloadPaketFile() [Test] public void GetLatestVersion_PaketFileNotCorrupt_DontDownloadPaketFile() { + const string hashFile = @"C:\hash.txt"; + //arrange var content = Guid.NewGuid().ToByteArray(); var sha = new SHA256Managed(); @@ -194,11 +198,11 @@ public void GetLatestVersion_PaketFileNotCorrupt_DontDownloadPaketFile() var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); mockEffectiveStrategy.Setup(x => x.GetLatestVersion(true)).Throws().Verifiable(); mockFileProxy.Setup(x => x.OpenRead(It.IsAny())).Returns(new MemoryStream(content)); - mockFileProxy.Setup(x => x.ReadAllLines(It.IsAny())).Returns(new[] { hash + " paket.exe" }); + mockFileProxy.Setup(x => x.ReadAllLines(hashFile)).Returns(new[] { hash + " paket.exe" }); mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - sut.DownloadVersion("any", "any", null); + sut.DownloadVersion("any", "any", hashFile); //assert mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); @@ -208,18 +212,20 @@ public void GetLatestVersion_PaketFileNotCorrupt_DontDownloadPaketFile() [Test] public void GetLatestVersion_PaketHashFileExistsButIsCorrupt_DeleteHashFileAndThrowException() { + const string hashFile = @"C:\hash.txt"; + //arrange mockEffectiveStrategy.Setup(x => x.GetLatestVersion(true)).Throws().Verifiable(); mockFileProxy.Setup(x => x.OpenRead(It.IsAny())).Returns(new MemoryStream(Guid.NewGuid().ToByteArray())); - mockFileProxy.Setup(x => x.ReadAllLines(It.IsAny())).Returns(new[] { Guid.NewGuid().ToString().Replace("-", String.Empty) + " not-paket.exe" }); + mockFileProxy.Setup(x => x.ReadAllLines(hashFile)).Returns(new[] { Guid.NewGuid().ToString().Replace("-", String.Empty) + " not-paket.exe" }); mockFileProxy.Setup(x => x.FileExists(It.IsAny())).Returns(true); //act - Assert.Throws(() => sut.DownloadVersion("any", "any", null)); + Assert.Throws(() => sut.DownloadVersion("any", "any", hashFile)); //assert mockEffectiveStrategy.Verify(x => x.DownloadVersion(It.IsAny(), It.IsAny(), null), Times.Never); - mockFileProxy.Verify(x => x.DeleteFile(ItHasFilename("paket-sha256.txt"))); + mockFileProxy.Verify(x => x.DeleteFile(hashFile)); } public string ItHasFilename(string filename) From 45ca6e5a43420e09f00328393a67af0a36a3a165 Mon Sep 17 00:00:00 2001 From: Julien Roncaglia Date: Fri, 26 May 2017 23:20:26 +0200 Subject: [PATCH 6/6] Add more tests --- .../CacheDownloadStrategy.cs | 2 +- .../CacheDownloadStrategyTest.cs | 48 ++++++++++ .../GitHubDownloadStrategyTest.cs | 91 +++++++++++++++++-- .../NugetDownloadStrategyTests.cs | 17 ++++ ...rarilyIgnoreUpdatesDownloadStrategyTest.cs | 20 ++++ 5 files changed, 170 insertions(+), 8 deletions(-) diff --git a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs index 40df75780f..bbe9ccff81 100644 --- a/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs +++ b/src/Paket.Bootstrapper/DownloadStrategies/CacheDownloadStrategy.cs @@ -146,7 +146,7 @@ private string GetLatestVersionInCache(bool ignorePrerelease) .FirstOrDefault() ?? "0"; } - private string GetHashFilePathInCache(string version) + public string GetHashFilePathInCache(string version) { return Path.Combine(_paketCacheDir, version, "paket-sha256.txt"); } diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs index 0a2b49163a..2b42fe95e3 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/CacheDownloadStrategyTest.cs @@ -232,5 +232,53 @@ public string ItHasFilename(string filename) { return It.IsRegex($@"\w*[\\/]{filename}"); } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void CanDownloadHashFile(bool can) + { + mockEffectiveStrategy.SetupGet(x => x.CanDownloadHashFile).Returns(can); + Assert.That(sut.CanDownloadHashFile, Is.EqualTo(can)); + } + + [Test] + public void DownloadHashFile_NotSupported() + { + mockEffectiveStrategy.SetupGet(x => x.CanDownloadHashFile).Returns(false); + + var hashFilePath = sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.Null); + } + + [Test] + public void DownloadHashFile_PresentInCache() + { + mockEffectiveStrategy.SetupGet(x => x.CanDownloadHashFile).Returns(true); + var pathInCache = sut.GetHashFilePathInCache("42.0"); + mockFileProxy.Setup(x => x.FileExists(pathInCache)).Returns(true); + + var hashFilePath = sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.EqualTo(pathInCache)); + mockEffectiveStrategy.Verify(x => x.DownloadHashFile(It.IsAny()), Times.Never); + } + + [Test] + public void DownloadHashFile_NotInCache() + { + const string pathFromEffectiveStrategy = @"C:\hash.txt"; + mockEffectiveStrategy.Setup(x => x.DownloadHashFile(It.IsAny())).Returns(pathFromEffectiveStrategy); + mockEffectiveStrategy.SetupGet(x => x.CanDownloadHashFile).Returns(true); + var pathInCache = sut.GetHashFilePathInCache("42.0"); + mockFileProxy.Setup(x => x.FileExists(pathInCache)).Returns(false); + + var hashFilePath = sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.EqualTo(pathInCache)); + mockEffectiveStrategy.Verify(x => x.DownloadHashFile("42.0"), Times.Once); + mockFileProxy.Verify(x => x.CopyFile(pathFromEffectiveStrategy, pathInCache, true), Times.Once); + } } } diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs index c72a7e15fc..f82245f743 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/GitHubDownloadStrategyTest.cs @@ -1,6 +1,7 @@ -using System.IO; +using System; +using System.IO; using System.Reflection; -using System.Text; +using System.Security.Cryptography; using Moq; using NUnit.Framework; using Paket.Bootstrapper.DownloadStrategies; @@ -53,19 +54,77 @@ public void GetLatestVersion_Prerelease() } [Test] - public void DownloadVersion() + public void DownloadVersion_NoHash() { //arrange var tempFileName = BootstrapperHelper.GetTempFile("paket"); - mockWebProxy.Setup(x => x.DownloadFile(It.IsAny(), It.IsAny())).Verifiable(); //act sut.DownloadVersion("2.57.1", "paketExeLocation", null); //assert - mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName)); - mockFileProxy.Verify(x => x.CopyFile(tempFileName, "paketExeLocation", true)); - mockFileProxy.Verify(x => x.DeleteFile(tempFileName)); + mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName), Times.Once); + mockFileProxy.Verify(x => x.CopyFile(tempFileName, "paketExeLocation", true), Times.Once); + mockFileProxy.Verify(x => x.DeleteFile(tempFileName), Times.Once); + } + + [Test] + public void DownloadVersion_HashFileNotFound() + { + //arrange + var tempFileName = BootstrapperHelper.GetTempFile("paket"); + + //act + sut.DownloadVersion("2.57.1", "paketExeLocation", @"C:\does_not_exists.txt"); + + //assert + mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName), Times.Once); + mockFileProxy.Verify(x => x.CopyFile(tempFileName, "paketExeLocation", true), Times.Once); + mockFileProxy.Verify(x => x.DeleteFile(tempFileName), Times.Once); + } + + [Test] + public void DownloadVersion_InvalidHashRetryOnce() + { + //arrange + var content = Guid.NewGuid().ToByteArray(); + var sha = new SHA256Managed(); + var checksum = sha.ComputeHash(new MemoryStream(content)); + var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); + mockFileProxy.Setup(x => x.OpenRead(It.IsAny())).Returns(() => new MemoryStream(Guid.NewGuid().ToByteArray())); + mockFileProxy.Setup(x => x.FileExists(@"C:\invalid.txt")).Returns(true); + mockFileProxy.Setup(x => x.ReadAllLines(@"C:\invalid.txt")).Returns(new[] { hash + " paket.exe" }); + var tempFileName = BootstrapperHelper.GetTempFile("paket"); + + //act + sut.DownloadVersion("2.57.1", "paketExeLocation", @"C:\invalid.txt"); + + //assert + mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName), Times.Exactly(2)); + mockFileProxy.Verify(x => x.CopyFile(tempFileName, "paketExeLocation", true), Times.Once); + mockFileProxy.Verify(x => x.DeleteFile(tempFileName), Times.Once); + } + + [Test] + public void DownloadVersion_ValidHashOk() + { + //arrange + var content = Guid.NewGuid().ToByteArray(); + var sha = new SHA256Managed(); + var checksum = sha.ComputeHash(new MemoryStream(content)); + var hash = BitConverter.ToString(checksum).Replace("-", String.Empty); + mockFileProxy.Setup(x => x.OpenRead(It.IsAny())).Returns(new MemoryStream(content)); + mockFileProxy.Setup(x => x.FileExists(@"C:\valid.txt")).Returns(true); + mockFileProxy.Setup(x => x.ReadAllLines(@"C:\valid.txt")).Returns(new[] { hash + " paket.exe" }); + var tempFileName = BootstrapperHelper.GetTempFile("paket"); + + //act + sut.DownloadVersion("2.57.1", "paketExeLocation", @"C:\valid.txt"); + + //assert + mockWebProxy.Verify(x => x.DownloadFile(It.IsAny(), tempFileName), Times.Once); + mockFileProxy.Verify(x => x.CopyFile(tempFileName, "paketExeLocation", true), Times.Once); + mockFileProxy.Verify(x => x.DeleteFile(tempFileName), Times.Once); } [Test] @@ -86,5 +145,23 @@ public void SelfUpdate() mockFileProxy.Verify(x => x.MoveFile(Assembly.GetAssembly(typeof(GitHubDownloadStrategy)).Location, tempFileNameOld)); mockFileProxy.Verify(x => x.MoveFile(tempFileNameNew, Assembly.GetAssembly(typeof(GitHubDownloadStrategy)).Location)); } + + [Test] + public void DownloadHashFile() + { + var expectedPath = BootstrapperHelper.GetTempFile("paket-sha256.txt"); + var expectedUrl = string.Format(GitHubDownloadStrategy.Constants.PaketCheckSumDownloadUrlTemplate, "42.0"); + + var hashFilePath = sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.EqualTo(expectedPath)); + mockWebProxy.Verify(x => x.DownloadFile(expectedUrl, expectedPath), Times.Once); + } + + [Test] + public void CanDownloadHashFile() + { + Assert.That(sut.CanDownloadHashFile, Is.True); + } } } \ No newline at end of file diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs index 97f1ed87eb..a11a30c2d1 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/NugetDownloadStrategyTests.cs @@ -312,5 +312,22 @@ public void NugetFolder_SelfUpdate_FailsWhenNullIsSpecified() mockFileProxy.Verify(x => x.CopyFile(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never); } + [Test] + public void DownloadHashFile() + { + CreateSystemUnderTestWithDefaultApi(); + + var hashFilePath = sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.Null); + } + + [Test] + public void CanDownloadHashFile() + { + CreateSystemUnderTestWithDefaultApi(); + + Assert.That(sut.CanDownloadHashFile, Is.False); + } } } \ No newline at end of file diff --git a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs index f8c9a0edab..de7c3be8e5 100644 --- a/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs +++ b/tests/Paket.Bootstrapper.Tests/DownloadStrategies/TemporarilyIgnoreUpdatesDownloadStrategyTest.cs @@ -171,6 +171,26 @@ public void DownloadVersion_Touches_Target() _mockEffectiveStrategy.Verify(); _mockFileProxy.Verify(); } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void CanDownloadHashFile(bool can) + { + _mockEffectiveStrategy.SetupGet(x => x.CanDownloadHashFile).Returns(can); + Assert.That(_sut.CanDownloadHashFile, Is.EqualTo(can)); + } + + [Test] + public void DownloadHashFile() + { + _mockEffectiveStrategy.Setup(x => x.DownloadHashFile("42.0")).Returns(@"C:\42.txt"); + + var hashFilePath = _sut.DownloadHashFile("42.0"); + + Assert.That(hashFilePath, Is.EqualTo(@"C:\42.txt")); + _mockEffectiveStrategy.Verify(x => x.DownloadHashFile("42.0"), Times.Once); + } } }