Add test files, update namespaces

This commit is contained in:
Paul Betts
2014-07-31 14:41:16 +02:00
parent 4f4d25112d
commit 3313a0bf31
7 changed files with 1492 additions and 0 deletions

493
test/ApplyReleasesTests.cs Normal file
View File

@@ -0,0 +1,493 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using NuGet;
using Splat;
using Squirrel;
using Squirrel.Tests.TestHelpers;
using Xunit;
namespace Squirrel.Tests
{
public class ApplyReleasesTests : IEnableLogger
{
[Serializable]
public class FakeUrlDownloader : IFileDownloader
{
public Task<byte[]> DownloadUrl(string url)
{
return Task.FromResult(new byte[0]);
}
public async Task DownloadFile(string url, string targetFile)
{
}
}
[Fact]
public void WhenNoNewReleasesAreAvailableTheListIsEmpty()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
Directory.CreateDirectory(Path.Combine(tempDir, "theApp"));
var packages = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packages);
var package = "Squirrel.Core.1.0.0.0-full.nupkg";
File.Copy(IntegrationTestHelper.GetPath("fixtures", package),
Path.Combine(packages, package));
var aGivenPackage = Path.Combine(packages, package);
var baseEntry = ReleaseEntry.GenerateFromFile(aGivenPackage);
var updateInfo = UpdateInfo.Create(baseEntry, new[] { baseEntry }, "dontcare", FrameworkVersion.Net40);
Assert.Empty(updateInfo.ReleasesToApply);
}
}
[Fact]
public void ThrowsWhenOnlyDeltaReleasesAreAvailable()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir))
{
Directory.CreateDirectory(Path.Combine(tempDir, "theApp"));
var packages = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packages);
var baseFile = "Squirrel.Core.1.0.0.0-full.nupkg";
File.Copy(IntegrationTestHelper.GetPath("fixtures", baseFile),
Path.Combine(packages, baseFile));
var basePackage = Path.Combine(packages, baseFile);
var baseEntry = ReleaseEntry.GenerateFromFile(basePackage);
var deltaFile = "Squirrel.Core.1.1.0.0-delta.nupkg";
File.Copy(IntegrationTestHelper.GetPath("fixtures", deltaFile),
Path.Combine(packages, deltaFile));
var deltaPackage = Path.Combine(packages, deltaFile);
var deltaEntry = ReleaseEntry.GenerateFromFile(deltaPackage);
Assert.Throws<Exception>(
() => UpdateInfo.Create(baseEntry, new[] { deltaEntry }, "dontcare", FrameworkVersion.Net40));
}
}
[Fact]
public void ApplyReleasesWithOneReleaseFile()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
string packagesDir = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packagesDir);
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.0.0.0-full.nupkg"));
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40);
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.ApplyReleases(updateInfo, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2,1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
var filesToFind = new[] {
new {Name = "NLog.dll", Version = new Version("2.0.0.0")},
new {Name = "NSync.Core.dll", Version = new Version("1.1.0.0")},
new {Name = Path.Combine("sub", "Ionic.Zip.dll"), Version = new Version("1.9.1.8")},
};
filesToFind.ForEach(x => {
var path = Path.Combine(tempDir, "theApp", "app-1.1.0.0", x.Name);
this.Log().Info("Looking for {0}", path);
File.Exists(path).ShouldBeTrue();
var vi = FileVersionInfo.GetVersionInfo(path);
var verInfo = new Version(vi.FileVersion ?? "1.0.0.0");
x.Version.ShouldEqual(verInfo);
});
}
}
[Fact]
public void ApplyReleaseWhichRemovesAFile()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
string packagesDir = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packagesDir);
new[] {
"Squirrel.Core.1.1.0.0-full.nupkg",
"Squirrel.Core.1.2.0.0-full.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.2.0.0-full.nupkg"));
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40);
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.ApplyReleases(updateInfo, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2,1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
var rootDirectory = Path.Combine(tempDir, "theApp", "app-1.2.0.0");
new[] {
new {Name = "NLog.dll", Version = new Version("2.0.0.0")},
new {Name = "NSync.Core.dll", Version = new Version("1.1.0.0")},
}.ForEach(x => {
var path = Path.Combine(rootDirectory, x.Name);
this.Log().Info("Looking for {0}", path);
File.Exists(path).ShouldBeTrue();
});
var removedFile = Path.Combine("sub", "Ionic.Zip.dll");
var deployedPath = Path.Combine(rootDirectory, removedFile);
File.Exists(deployedPath).ShouldBeFalse();
}
}
[Fact]
public void ApplyReleaseWhichMovesAFileToADifferentDirectory()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir))
{
string packagesDir = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packagesDir);
new[] {
"Squirrel.Core.1.1.0.0-full.nupkg",
"Squirrel.Core.1.3.0.0-full.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.3.0.0-full.nupkg"));
var updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40);
updateInfo.ReleasesToApply.Contains(latestFullEntry).ShouldBeTrue();
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.ApplyReleases(updateInfo, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2, 1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
var rootDirectory = Path.Combine(tempDir, "theApp", "app-1.3.0.0");
new[] {
new {Name = "NLog.dll", Version = new Version("2.0.0.0")},
new {Name = "NSync.Core.dll", Version = new Version("1.1.0.0")},
}.ForEach(x =>
{
var path = Path.Combine(rootDirectory, x.Name);
this.Log().Info("Looking for {0}", path);
File.Exists(path).ShouldBeTrue();
});
var oldFile = Path.Combine(rootDirectory, "sub", "Ionic.Zip.dll");
File.Exists(oldFile).ShouldBeFalse();
var newFile = Path.Combine(rootDirectory, "other", "Ionic.Zip.dll");
File.Exists(newFile).ShouldBeTrue();
}
}
[Fact]
public void ApplyReleasesWithDeltaReleases()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
string packagesDir = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packagesDir);
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.0.0.0-full.nupkg"));
var deltaEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-delta.nupkg"));
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "Squirrel.Core.1.1.0.0-full.nupkg"));
var updateInfo = UpdateInfo.Create(baseEntry, new[] { deltaEntry, latestFullEntry }, packagesDir, FrameworkVersion.Net40);
updateInfo.ReleasesToApply.Contains(deltaEntry).ShouldBeTrue();
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.ApplyReleases(updateInfo, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2,1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
var filesToFind = new[] {
new {Name = "NLog.dll", Version = new Version("2.0.0.0")},
new {Name = "NSync.Core.dll", Version = new Version("1.1.0.0")},
new {Name = Path.Combine("sub", "Ionic.Zip.dll"), Version = new Version("1.9.1.8")},
};
filesToFind.ForEach(x => {
var path = Path.Combine(tempDir, "theApp", "app-1.1.0.0", x.Name);
this.Log().Info("Looking for {0}", path);
File.Exists(path).ShouldBeTrue();
var vi = FileVersionInfo.GetVersionInfo(path);
var verInfo = new Version(vi.FileVersion ?? "1.0.0.0");
x.Version.ShouldEqual(verInfo);
});
}
}
[Fact]
public void CreateFullPackagesFromDeltaSmokeTest()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
Directory.CreateDirectory(Path.Combine(tempDir, "theApp", "packages"));
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg"
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(tempDir, "theApp", "packages", x)));
var urlDownloader = new Mock<IUrlDownloader>();
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, urlDownloader.Object);
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(tempDir, "theApp", "packages", "Squirrel.Core.1.0.0.0-full.nupkg"));
var deltaEntry = ReleaseEntry.GenerateFromFile(Path.Combine(tempDir, "theApp", "packages", "Squirrel.Core.1.1.0.0-delta.nupkg"));
var resultObs = (IObservable<ReleaseEntry>)fixture.GetType().GetMethod("createFullPackagesFromDeltas", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(fixture, new object[] { new[] {deltaEntry}, baseEntry });
var result = resultObs.Last();
var zp = new ZipPackage(Path.Combine(tempDir, "theApp", "packages", result.Filename));
zp.Version.ToString().ShouldEqual("1.1.0.0");
}
}
[Fact(Skip = "TODO")]
public void ShouldCallAppUninstallOnTheOldVersion()
{
throw new NotImplementedException();
}
[Fact]
public void CallAppInstallOnTheJustInstalledVersion()
{
string tempDir;
using (acquireEnvVarLock())
using (Utility.WithTempDirectory(out tempDir)) {
var di = Path.Combine(tempDir, "theApp", "app-1.1.0.0");
Directory.CreateDirectory(di);
File.Copy(getPathToSquirrelTestTarget(), Path.Combine(di, "SquirrelIAppUpdateTestTarget.exe"));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, null);
this.Log().Info("Invoking post-install");
var mi = fixture.GetType().GetMethod("runPostInstallOnDirectory", BindingFlags.NonPublic | BindingFlags.Instance);
mi.Invoke(fixture, new object[] { di, true, new Version(1, 1, 0, 0), Enumerable.Empty<ShortcutCreationRequest>() });
getEnvVar("AppInstall_Called").ShouldEqual("1");
getEnvVar("VersionInstalled_Called").ShouldEqual("1.1.0.0");
}
}
[Fact]
public void ShouldCreateAppShortcutsBasedOnClientExe()
{
string tempDir;
using (acquireEnvVarLock())
using (Utility.WithTempDirectory(out tempDir))
using (setEnvVar("ShortcutDir", tempDir)) {
var di = Path.Combine(tempDir, "theApp", "app-1.1.0.0");
Directory.CreateDirectory(di);
File.Copy(getPathToSquirrelTestTarget(), Path.Combine(di, "SquirrelIAppUpdateTestTarget.exe"));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, null);
this.Log().Info("Invoking post-install");
var mi = fixture.GetType().GetMethod("runPostInstallOnDirectory", BindingFlags.NonPublic | BindingFlags.Instance);
mi.Invoke(fixture, new object[] { di, true, new Version(1, 1, 0, 0), Enumerable.Empty<ShortcutCreationRequest>() });
File.Exists(Path.Combine(tempDir, "Foo.lnk")).ShouldBeTrue();
}
}
[Fact(Skip = "TODO")]
public void DeletedShortcutsShouldntBeRecreatedOnUpgrade()
{
throw new NotImplementedException();
}
[Fact]
public void IfAppSetupThrowsWeFailTheInstall()
{
string tempDir;
using (acquireEnvVarLock())
using (setShouldThrow())
using (Utility.WithTempDirectory(out tempDir)) {
var di = Path.Combine(tempDir, "theApp", "app-1.1.0.0");
Directory.CreateDirectory(di);
File.Copy(getPathToSquirrelTestTarget(), Path.Combine(di, "SquirrelIAppUpdateTestTarget.exe"));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, null);
bool shouldDie = true;
try {
this.Log().Info("Invoking post-install");
var mi = fixture.GetType().GetMethod("runPostInstallOnDirectory", BindingFlags.NonPublic | BindingFlags.Instance);
mi.Invoke(fixture, new object[] { di, true, new Version(1, 1, 0, 0), Enumerable.Empty<ShortcutCreationRequest>() });
} catch (TargetInvocationException ex) {
this.Log().Info("Expected to receive Exception", ex);
// NB: This is the exception explicitly rigged in OnAppInstall
if (ex.InnerException is FileNotFoundException) {
shouldDie = false;
} else {
this.Log().ErrorException("Expected FileNotFoundException, didn't get it", ex);
}
}
shouldDie.ShouldBeFalse();
}
}
[Fact]
public void ExecutablesPinnedToTaskbarShouldPointToNewVersion()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
string packagesDir = Path.Combine(tempDir, "theApp", "packages");
Directory.CreateDirectory(packagesDir);
new[] {
"SampleUpdatingApp.1.0.0.0.nupkg",
"SampleUpdatingApp.1.1.0.0.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(packagesDir, x)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, new FakeUrlDownloader());
var baseEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.0.0.0.nupkg"));
var latestFullEntry = ReleaseEntry.GenerateFromFile(Path.Combine(packagesDir, "SampleUpdatingApp.1.1.0.0.nupkg"));
var updateInfo = UpdateInfo.Create(null, new[] { baseEntry }, packagesDir, FrameworkVersion.Net40);
using (fixture) {
fixture.ApplyReleases(updateInfo).ToList().First();
}
var oldExecutable = Path.Combine(tempDir, "theApp", "app-1.0.0.0", "SampleUpdatingApp.exe");
File.Exists(oldExecutable).ShouldBeTrue();
TaskbarHelper.PinToTaskbar(oldExecutable);
updateInfo = UpdateInfo.Create(baseEntry, new[] { latestFullEntry }, packagesDir, FrameworkVersion.Net40);
using (fixture) {
fixture.ApplyReleases(updateInfo).ToList().First();
}
var newExecutable = Path.Combine(tempDir, "theApp", "app-1.1.0.0", "SampleUpdatingApp.exe");
File.Exists(newExecutable).ShouldBeTrue();
TaskbarHelper.IsPinnedToTaskbar(newExecutable).ShouldBeTrue();
Utility.Retry(() => TaskbarHelper.UnpinFromTaskbar(newExecutable));
}
}
string getPathToSquirrelTestTarget()
{
#if DEBUG
const string config = "Debug";
#else
const string config = "Release";
#endif
var ret = IntegrationTestHelper.GetPath("..", "SquirrelIAppUpdateTestTarget", "bin", config, "SquirrelIAppUpdateTestTarget.exe");
File.Exists(ret).ShouldBeTrue();
return ret;
}
static readonly object gate = 42;
static IDisposable acquireEnvVarLock()
{
// NB: Since we use process-wide environment variables to communicate
// across AppDomains, we have to serialize all of the tests
Monitor.Enter(gate);
return Disposable.Create(() => {
// NB: The test target sets a bunch of environment variables that
// we should clear out, but there's no way for the test target to
// clean these up correctly
Environment.GetEnvironmentVariables().Keys.OfType<string>()
.Where(x => x.StartsWith("__IAPPSETUP_TEST"))
.ForEach(x => Environment.SetEnvironmentVariable(x, null));
Monitor.Exit(gate);
});
}
static IDisposable setShouldThrow()
{
return setEnvVar("ShouldThrow", true);
}
static string getEnvVar(string name)
{
return Environment.GetEnvironmentVariable(String.Format("__IAPPSETUP_TEST_{0}", name.ToUpperInvariant()));
}
static IDisposable setEnvVar(string name, object val)
{
var prevVal = Environment.GetEnvironmentVariable(name);
Environment.SetEnvironmentVariable(String.Format("__IAPPSETUP_TEST_{0}", name.ToUpperInvariant()), val.ToString(), EnvironmentVariableTarget.Process);
return Disposable.Create(() => Environment.SetEnvironmentVariable(name, prevVal));
}
}
}

178
test/CheckForUpdateTests.cs Normal file
View File

@@ -0,0 +1,178 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using Squirrel.Tests.TestHelpers;
using Xunit;
namespace Squirrel.Tests
{
public class CheckForUpdateTests
{
[Fact]
public void NewReleasesShouldBeDetected()
{
string localReleasesFile = Path.Combine(".", "theApp", "packages", "RELEASES");
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.OpenRead())
.Returns(File.OpenRead(IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOh")));
var fs = new Mock<IFileSystemFactory>();
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
var urlDownloader = new Mock<IUrlDownloader>();
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object);
var result = default(UpdateInfo);
using (fixture) {
result = fixture.CheckForUpdate().First();
}
Assert.NotNull(result);
Assert.Equal(1, result.ReleasesToApply.Single().Version.Major);
Assert.Equal(1, result.ReleasesToApply.Single().Version.Minor);
}
[Fact]
public void NoLocalReleasesFileMeansWeStartFromScratch()
{
string localPackagesDir = Path.Combine(".", "theApp", "packages");
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.Exists).Returns(false);
var dirInfo = new Mock<DirectoryInfoBase>();
dirInfo.Setup(x => x.Exists).Returns(true);
var fs = new Mock<IFileSystemFactory>();
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
fs.Setup(x => x.CreateDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.DeleteDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
var urlDownloader = new Mock<IUrlDownloader>();
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object);
using (fixture) {
fixture.CheckForUpdate().First();
}
fs.Verify(x => x.CreateDirectoryRecursive(localPackagesDir), Times.Once());
fs.Verify(x => x.DeleteDirectoryRecursive(localPackagesDir), Times.Once());
}
[Fact]
public void NoLocalDirectoryMeansWeStartFromScratch()
{
string localPackagesDir = Path.Combine(".", "theApp", "packages");
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.Exists).Returns(false);
var dirInfo = new Mock<DirectoryInfoBase>();
dirInfo.Setup(x => x.Exists).Returns(false);
var fs = new Mock<IFileSystemFactory>();
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
fs.Setup(x => x.CreateDirectoryRecursive(It.IsAny<string>())).Verifiable();
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
var urlDownloader = new Mock<IUrlDownloader>();
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object);
using (fixture) {
fixture.CheckForUpdate().First();
}
fs.Verify(x => x.CreateDirectoryRecursive(localPackagesDir), Times.Once());
}
[Fact]
public void CorruptedReleaseFileMeansWeStartFromScratch()
{
string localPackagesDir = Path.Combine(".", "theApp", "packages");
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.Exists).Returns(true);
fileInfo.Setup(x => x.OpenRead())
.Returns(new MemoryStream(Encoding.UTF8.GetBytes("lol this isn't right")));
var dirInfo = new Mock<DirectoryInfoBase>();
dirInfo.Setup(x => x.Exists).Returns(true);
var fs = new Mock<IFileSystemFactory>();
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
fs.Setup(x => x.CreateDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.DeleteDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
var urlDownloader = new Mock<IUrlDownloader>();
var dlPath = IntegrationTestHelper.GetPath("fixtures", "RELEASES-OnePointOne");
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
.Returns(Observable.Return(File.ReadAllText(dlPath, Encoding.UTF8)));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object);
using (fixture) {
fixture.CheckForUpdate().First();
}
fs.Verify(x => x.CreateDirectoryRecursive(localPackagesDir), Times.Once());
fs.Verify(x => x.DeleteDirectoryRecursive(localPackagesDir), Times.Once());
}
[Fact]
public void CorruptRemoteFileShouldThrowOnCheck()
{
string localPackagesDir = Path.Combine(".", "theApp", "packages");
string localReleasesFile = Path.Combine(localPackagesDir, "RELEASES");
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.Exists).Returns(false);
var dirInfo = new Mock<DirectoryInfoBase>();
dirInfo.Setup(x => x.Exists).Returns(true);
var fs = new Mock<IFileSystemFactory>();
fs.Setup(x => x.GetFileInfo(localReleasesFile)).Returns(fileInfo.Object);
fs.Setup(x => x.CreateDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.DeleteDirectoryRecursive(localPackagesDir)).Verifiable();
fs.Setup(x => x.GetDirectoryInfo(localPackagesDir)).Returns(dirInfo.Object);
var urlDownloader = new Mock<IUrlDownloader>();
urlDownloader.Setup(x => x.DownloadUrl(It.IsAny<string>(), It.IsAny<IObserver<int>>()))
.Returns(Observable.Return("lol this isn't right"));
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object);
using (fixture) {
Assert.Throws<Exception>(() => fixture.CheckForUpdate().First());
}
}
[Fact(Skip = "TODO")]
public void IfLocalVersionGreaterThanRemoteWeRollback()
{
throw new NotImplementedException();
}
[Fact(Skip = "TODO")]
public void IfLocalAndRemoteAreEqualThenDoNothing()
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,203 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Splat;
using Squirrel.Tests.TestHelpers;
using Xunit;
namespace Squirrel.Tests
{
public class DownloadReleasesTests : IEnableLogger
{
[Fact]
public void ChecksumShouldPassOnValidPackages()
{
var filename = "Squirrel.Core.1.0.0.0.nupkg";
var nuGetPkg = IntegrationTestHelper.GetPath("fixtures", filename);
var fs = new Mock<IFileSystemFactory>();
var urlDownloader = new Mock<IUrlDownloader>();
ReleaseEntry entry;
using (var f = File.OpenRead(nuGetPkg)) {
entry = ReleaseEntry.GenerateFromFile(f, filename);
}
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.OpenRead()).Returns(File.OpenRead(nuGetPkg));
fileInfo.Setup(x => x.Exists).Returns(true);
fileInfo.Setup(x => x.Length).Returns(new FileInfo(nuGetPkg).Length);
fs.Setup(x => x.GetFileInfo(Path.Combine(".", "theApp", "packages", filename))).Returns(fileInfo.Object);
var fixture = ExposedObject.From(
new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object));
fixture.checksumPackage(entry);
}
[Fact]
public void ChecksumShouldFailIfFilesAreMissing()
{
var filename = "Squirrel.Core.1.0.0.0.nupkg";
var nuGetPkg = IntegrationTestHelper.GetPath("fixtures", filename);
var fs = new Mock<IFileSystemFactory>();
var urlDownloader = new Mock<IUrlDownloader>();
ReleaseEntry entry;
using (var f = File.OpenRead(nuGetPkg)) {
entry = ReleaseEntry.GenerateFromFile(f, filename);
}
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.OpenRead()).Returns(File.OpenRead(nuGetPkg));
fileInfo.Setup(x => x.Exists).Returns(false);
fs.Setup(x => x.GetFileInfo(Path.Combine(".", "theApp", "packages", filename))).Returns(fileInfo.Object);
var fixture = ExposedObject.From(
new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object));
bool shouldDie = true;
try {
// NB: We can't use Assert.Throws here because the binder
// will try to pick the wrong method
fixture.checksumPackage(entry);
} catch (Exception) {
shouldDie = false;
}
shouldDie.ShouldBeFalse();
}
[Fact]
public void ChecksumShouldFailIfFilesAreBogus()
{
var filename = "Squirrel.Core.1.0.0.0.nupkg";
var nuGetPkg = IntegrationTestHelper.GetPath("fixtures", filename);
var fs = new Mock<IFileSystemFactory>();
var urlDownloader = new Mock<IUrlDownloader>();
ReleaseEntry entry;
using (var f = File.OpenRead(nuGetPkg)) {
entry = ReleaseEntry.GenerateFromFile(f, filename);
}
var fileInfo = new Mock<FileInfoBase>();
fileInfo.Setup(x => x.OpenRead()).Returns(new MemoryStream(Encoding.UTF8.GetBytes("Lol broken")));
fileInfo.Setup(x => x.Exists).Returns(true);
fileInfo.Setup(x => x.Length).Returns(new FileInfo(nuGetPkg).Length);
fileInfo.Setup(x => x.Delete()).Verifiable();
fs.Setup(x => x.GetFileInfo(Path.Combine(".", "theApp", "packages", filename))).Returns(fileInfo.Object);
var fixture = ExposedObject.From(
new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, ".", fs.Object, urlDownloader.Object));
bool shouldDie = true;
try {
fixture.checksumPackage(entry);
} catch (Exception ex) {
this.Log().InfoException("Checksum failure", ex);
shouldDie = false;
}
shouldDie.ShouldBeFalse();
fileInfo.Verify(x => x.Delete(), Times.Once());
}
[Fact]
public void DownloadReleasesFromHttpServerIntegrationTest()
{
string tempDir = null;
var updateDir = new DirectoryInfo(IntegrationTestHelper.GetPath("..", "SampleUpdatingApp", "SampleReleasesFolder"));
IDisposable disp;
try {
var httpServer = new StaticHttpServer(30405, updateDir.FullName);
disp = httpServer.Start();
}
catch (HttpListenerException) {
Assert.False(true, @"Windows sucks, go run 'netsh http add urlacl url=http://+:30405/ user=MYMACHINE\MyUser");
return;
}
var entriesToDownload = updateDir.GetFiles("*.nupkg")
.Select(x => ReleaseEntry.GenerateFromFile(x.FullName))
.ToArray();
entriesToDownload.Count().ShouldBeGreaterThan(0);
using (disp)
using (Utility.WithTempDirectory(out tempDir)) {
// NB: This is normally done by CheckForUpdates, but since
// we're skipping that in the test we have to do it ourselves
Directory.CreateDirectory(Path.Combine(tempDir, "SampleUpdatingApp", "packages"));
var fixture = new UpdateManager("http://localhost:30405", "SampleUpdatingApp", FrameworkVersion.Net40, tempDir);
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.DownloadReleases(entriesToDownload, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2,1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
entriesToDownload.ForEach(x => {
this.Log().Info("Looking for {0}", x.Filename);
var actualFile = Path.Combine(tempDir, "SampleUpdatingApp", "packages", x.Filename);
File.Exists(actualFile).ShouldBeTrue();
var actualEntry = ReleaseEntry.GenerateFromFile(actualFile);
actualEntry.SHA1.ShouldEqual(x.SHA1);
actualEntry.Version.ShouldEqual(x.Version);
});
}
}
[Fact]
public void DownloadReleasesFromFileDirectoryIntegrationTest()
{
string tempDir = null;
var updateDir = new DirectoryInfo(IntegrationTestHelper.GetPath("..", "SampleUpdatingApp", "SampleReleasesFolder"));
var entriesToDownload = updateDir.GetFiles("*.nupkg")
.Select(x => ReleaseEntry.GenerateFromFile(x.FullName))
.ToArray();
entriesToDownload.Count().ShouldBeGreaterThan(0);
using (Utility.WithTempDirectory(out tempDir)) {
// NB: This is normally done by CheckForUpdates, but since
// we're skipping that in the test we have to do it ourselves
Directory.CreateDirectory(Path.Combine(tempDir, "SampleUpdatingApp", "packages"));
var fixture = new UpdateManager(updateDir.FullName, "SampleUpdatingApp", FrameworkVersion.Net40, tempDir);
using (fixture) {
var progress = new ReplaySubject<int>();
fixture.DownloadReleases(entriesToDownload, progress).First();
this.Log().Info("Progress: [{0}]", String.Join(",", progress));
progress.Buffer(2,1).All(x => x.Count != 2 || x[1] > x[0]).First().ShouldBeTrue();
progress.Last().ShouldEqual(100);
}
entriesToDownload.ForEach(x => {
this.Log().Info("Looking for {0}", x.Filename);
var actualFile = Path.Combine(tempDir, "SampleUpdatingApp", "packages", x.Filename);
File.Exists(actualFile).ShouldBeTrue();
var actualEntry = ReleaseEntry.GenerateFromFile(actualFile);
actualEntry.SHA1.ShouldEqual(x.SHA1);
actualEntry.Version.ShouldEqual(x.Version);
});
}
}
}
}

325
test/InstallManagerTests.cs Normal file
View File

@@ -0,0 +1,325 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using NuGet;
using Squirrel;
using Squirrel.Tests.TestHelpers;
using Xunit;
namespace Squirrel.Tests
{
public class InstallManagerTests
{
[Fact(Skip="The Zip test has some zero values - too fast lol")]
public void EigenUpdateWithoutUpdateURL()
{
string dir;
string outDir;
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(out dir)) {
var di = new DirectoryInfo(dir);
var progress = new Subject<int>();
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, "SampleUpdatingApp.1.1.0.0.nupkg"));
var progressValues = new List<int>();
progress.Subscribe(progressValues.Add);
fixture.ExecuteInstall(dir, pkg, progress).Wait();
var filesToLookFor = new[] {
"SampleUpdatingApp\\app-1.1.0.0\\SampleUpdatingApp.exe",
"SampleUpdatingApp\\packages\\RELEASES",
"SampleUpdatingApp\\packages\\SampleUpdatingApp.1.1.0.0.nupkg",
};
filesToLookFor.ForEach(f => Assert.True(File.Exists(Path.Combine(outDir, f)), "Could not find file: " + f));
// Progress should be monotonically increasing
progressValues.Count.ShouldBeGreaterThan(2);
progressValues.Zip(progressValues.Skip(1), (prev, cur) => cur - prev).All(x => x > 0).ShouldBeTrue();
}
}
[Fact(Skip = "TODO")]
public void EigenUpdateWithUpdateURL()
{
throw new NotImplementedException();
}
[Fact(Skip="TODO")]
public void UpdateReportsProgress()
{
throw new NotImplementedException();
}
[Fact(Skip = "TODO")]
public void InstallHandlesAccessDenied()
{
throw new NotImplementedException();
}
[Fact]
public void InstallRunsHooks()
{
string dir;
string outDir;
var package = "SampleUpdatingApp.1.2.0.0.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package,out dir)) {
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
var generatedFile = Path.Combine(outDir, "SampleUpdatingApp", "app-1.2.0.0", "install");
Assert.True(File.Exists(generatedFile));
}
}
[Fact]
public void InstallRunsSpecificVersion()
{
string dir;
string outDir;
var package = "SampleUpdatingApp.1.2.0.0.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir))
{
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
var generatedFile = Path.Combine(outDir, "SampleUpdatingApp", "app-1.2.0.0", "install-1.2.0.0");
Assert.True(File.Exists(generatedFile));
}
}
[Fact]
public void InstallSkipsLatestVersion()
{
string dir;
string outDir;
var package = "SampleUpdatingApp.1.3.0.0.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir))
{
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
var generatedFile = Path.Combine(outDir, "SampleUpdatingApp", "app-1.3.0.0", "install-1.3.0.0");
Assert.False(File.Exists(generatedFile));
}
}
[Fact]
public void UninstallRunsHooks()
{
string dir;
string outDir;
var package = "SampleUpdatingApp.1.2.0.0.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir)) {
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
fixture.ExecuteUninstall(new Version("1.2.0.0")).Wait();
var generatedFile = Path.Combine(outDir, "uninstall");
Assert.True(File.Exists(generatedFile));
}
}
[Fact]
public void UninstallRunsSpecificVersion()
{
string dir;
string outDir;
var package = "SampleUpdatingApp.1.2.0.0.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir)) {
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
fixture.ExecuteUninstall(new Version("1.2.0.0")).Wait();
var generatedFile = Path.Combine(outDir, "uninstall-1.2.0.0");
Assert.True(File.Exists(generatedFile));
}
}
[Fact]
public void UninstallRemovesEverything()
{
string dir;
string appDir;
using (IntegrationTestHelper.WithFakeInstallDirectory(out dir))
using (IntegrationTestHelper.WithFakeAlreadyInstalledApp(out appDir)) {
var di = new DirectoryInfo(dir);
var progress = new Subject<int>();
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, appDir);
var progressValues = new List<int>();
progress.Subscribe(progressValues.Add);
fixture.ExecuteUninstall().First();
di = new DirectoryInfo(appDir);
di.GetDirectories().Any().ShouldBeFalse();
di.GetFiles().Any().ShouldBeFalse();
}
}
[Fact]
public void UninstallDoesntCrashOnMissingAppDirectory()
{
string dir;
string appDir;
InstallManager fixture;
using (IntegrationTestHelper.WithFakeInstallDirectory(out dir))
using (IntegrationTestHelper.WithFakeAlreadyInstalledApp(out appDir)) {
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
fixture = new InstallManager(bundledRelease, appDir);
}
fixture.ExecuteUninstall().First();
}
[Fact]
public void InstallWithContentInPackageDropsInSameFolder()
{
string dir;
string outDir;
var package = "ProjectWithContent.1.0.0.0-beta-full.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir))
{
try
{
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
var filesToLookFor = new[] {
"ProjectWithContent\\app-1.0.0.0\\project-with-content.exe",
"ProjectWithContent\\app-1.0.0.0\\some-words.txt",
"ProjectWithContent\\app-1.0.0.0\\dir\\item-in-subdirectory.txt",
"ProjectWithContent\\packages\\RELEASES",
"ProjectWithContent\\packages\\ProjectWithContent.1.0.0.0-beta-full.nupkg",
};
filesToLookFor.ForEach(f => Assert.True(File.Exists(Path.Combine(outDir, f)), "Could not find file: " + f));
}
finally
{
Directory.Delete(dir, true);
}
}
}
[Fact]
public void InstallLoadsAssemblyInSameFolder()
{
string dir;
string outDir;
var package = "DemoConsoleApp.1.0.0.0-full.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir))
{
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
var generatedFile = Path.Combine(outDir, "DemoConsoleApp", "app-1.0.0.0", "install");
Assert.True(File.Exists(generatedFile));
}
}
[Fact]
public void UninstallLoadsAssemblyInSameFolder()
{
string dir;
string outDir;
var package = "DemoConsoleApp.1.0.0.0-full.nupkg";
using (Utility.WithTempDirectory(out outDir))
using (IntegrationTestHelper.WithFakeInstallDirectory(package, out dir))
{
var di = new DirectoryInfo(dir);
var bundledRelease = ReleaseEntry.GenerateFromFile(di.GetFiles("*.nupkg").First().FullName);
var fixture = new InstallManager(bundledRelease, outDir);
var pkg = new ZipPackage(Path.Combine(dir, package));
fixture.ExecuteInstall(dir, pkg).Wait();
fixture.ExecuteUninstall().Wait();
var generatedFile = Path.Combine(outDir, "uninstall");
Assert.True(File.Exists(generatedFile));
}
}
}
}

View File

@@ -0,0 +1,23 @@
using NuGet;
using Squirrel;
using Squirrel.Tests.TestHelpers;
using Xunit;
using Assert = Xunit.Assert;
namespace Squirrel.Tests
{
public class PackageExtensionsTests
{
[Theory]
[InlineData("Squirrel.Core.1.0.0.0-full.nupkg", FrameworkVersion.Net40)]
[InlineData("Caliburn.Micro.1.5.2.nupkg", FrameworkVersion.Net45)]
public void DetectFrameworkVersion(string packageName, FrameworkVersion expected)
{
var path = IntegrationTestHelper.GetPath("fixtures", packageName);
var zip = new ZipPackage(path);
Assert.Equal(expected, zip.DetectFrameworkVersion());
}
}
}

View File

@@ -66,8 +66,13 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ApplyReleasesTests.cs" />
<Compile Include="CheckForUpdateTests.cs" />
<Compile Include="ContentTypeTests.cs" />
<Compile Include="DeltaPackageTests.cs" />
<Compile Include="DownloadReleasesTests.cs" />
<Compile Include="InstallManagerTests.cs" />
<Compile Include="PackageExtensionsTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ReleaseEntryTests.cs" />
<Compile Include="ReleasePackageTests.cs" />
@@ -77,6 +82,7 @@
<Compile Include="TestHelpers\ExposedObjectHelper.cs" />
<Compile Include="TestHelpers\IntegrationTestHelper.cs" />
<Compile Include="TestHelpers\StaticHttpServer.cs" />
<Compile Include="UpdateManagerTests.cs" />
<Compile Include="UtilityTests.cs" />
</ItemGroup>
<ItemGroup>

264
test/UpdateManagerTests.cs Normal file
View File

@@ -0,0 +1,264 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Squirrel;
using Squirrel.Tests.TestHelpers;
using Xunit;
namespace Squirrel.Tests
{
public class UpdateManagerTests
{
public class TimingOutUrlDownloader : IUrlDownloader
{
public IObservable<string> DownloadUrl(string url, IObserver<int> progress = null)
{
return Observable.Start<string>(new Func<string>(() => { throw new TimeoutException(); }));
}
public IObservable<Unit> QueueBackgroundDownloads(IEnumerable<string> urls, IEnumerable<string> localPaths, IObserver<int> progress = null)
{
throw new NotImplementedException();
}
}
public class UpdateLocalReleasesTests
{
[Fact]
public void UpdateLocalReleasesSmokeTest()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
var packageDir = Directory.CreateDirectory(Path.Combine(tempDir, "theApp", "packages"));
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x => File.Copy(IntegrationTestHelper.GetPath("fixtures", x), Path.Combine(tempDir, "theApp", "packages", x)));
var urlDownloader = new Mock<IUrlDownloader>();
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net40, tempDir, null, urlDownloader.Object);
using (fixture) {
fixture.UpdateLocalReleasesFile().Last();
}
var releasePath = Path.Combine(packageDir.FullName, "RELEASES");
File.Exists(releasePath).ShouldBeTrue();
var entries = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasePath, Encoding.UTF8));
entries.Count().ShouldEqual(3);
}
}
[Fact]
public void WhenBothFilesAreInSyncNoUpdatesAreApplied()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir))
{
var localPackages = Path.Combine(tempDir, "theApp", "packages");
var remotePackages = Path.Combine(tempDir, "releases");
Directory.CreateDirectory(localPackages);
Directory.CreateDirectory(remotePackages);
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x =>
{
var path = IntegrationTestHelper.GetPath("fixtures", x);
File.Copy(path, Path.Combine(localPackages, x));
File.Copy(path, Path.Combine(remotePackages, x));
});
var urlDownloader = new Mock<IUrlDownloader>();
var fixture = new UpdateManager(remotePackages, "theApp", FrameworkVersion.Net40, tempDir, null, urlDownloader.Object);
UpdateInfo updateInfo;
using (fixture)
{
// sync both release files
fixture.UpdateLocalReleasesFile().Last();
ReleaseEntry.BuildReleasesFile(remotePackages);
// check for an update
updateInfo = fixture.CheckForUpdate().Wait();
}
Assert.NotNull(updateInfo);
Assert.Empty(updateInfo.ReleasesToApply);
}
}
[Fact]
public void WhenRemoteReleasesDoNotHaveDeltasNoUpdatesAreApplied()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir))
{
var localPackages = Path.Combine(tempDir, "theApp", "packages");
var remotePackages = Path.Combine(tempDir, "releases");
Directory.CreateDirectory(localPackages);
Directory.CreateDirectory(remotePackages);
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x =>
{
var path = IntegrationTestHelper.GetPath("fixtures", x);
File.Copy(path, Path.Combine(localPackages, x));
});
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x =>
{
var path = IntegrationTestHelper.GetPath("fixtures", x);
File.Copy(path, Path.Combine(remotePackages, x));
});
var urlDownloader = new Mock<IUrlDownloader>();
var fixture = new UpdateManager(remotePackages, "theApp", FrameworkVersion.Net40, tempDir, null, urlDownloader.Object);
UpdateInfo updateInfo;
using (fixture)
{
// sync both release files
fixture.UpdateLocalReleasesFile().Last();
ReleaseEntry.BuildReleasesFile(remotePackages);
// check for an update
updateInfo = fixture.CheckForUpdate().Wait();
}
Assert.NotNull(updateInfo);
Assert.Empty(updateInfo.ReleasesToApply);
}
}
[Fact]
public void WhenTwoRemoteUpdatesAreAvailableChoosesDeltaVersion()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir))
{
var localPackages = Path.Combine(tempDir, "theApp", "packages");
var remotePackages = Path.Combine(tempDir, "releases");
Directory.CreateDirectory(localPackages);
Directory.CreateDirectory(remotePackages);
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
}.ForEach(x =>
{
var path = IntegrationTestHelper.GetPath("fixtures", x);
File.Copy(path, Path.Combine(localPackages, x));
});
new[] {
"Squirrel.Core.1.0.0.0-full.nupkg",
"Squirrel.Core.1.1.0.0-delta.nupkg",
"Squirrel.Core.1.1.0.0-full.nupkg",
}.ForEach(x =>
{
var path = IntegrationTestHelper.GetPath("fixtures", x);
File.Copy(path, Path.Combine(remotePackages, x));
});
var urlDownloader = new Mock<IUrlDownloader>();
var fixture = new UpdateManager(remotePackages, "theApp", FrameworkVersion.Net40, tempDir, null, urlDownloader.Object);
UpdateInfo updateInfo;
using (fixture)
{
// sync both release files
fixture.UpdateLocalReleasesFile().Last();
ReleaseEntry.BuildReleasesFile(remotePackages);
updateInfo = fixture.CheckForUpdate().Wait();
Assert.True(updateInfo.ReleasesToApply.First().IsDelta);
updateInfo = fixture.CheckForUpdate(ignoreDeltaUpdates:true).Wait();
Assert.False(updateInfo.ReleasesToApply.First().IsDelta);
}
}
}
[Fact]
public void WhenFolderDoesNotExistThrowHelpfulError()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
var directory = Path.Combine(tempDir, "missing-folder");
var fixture = new UpdateManager(directory, "MyAppName", FrameworkVersion.Net40);
using (fixture) {
Assert.Throws<SquirrelConfigurationException>(
() => fixture.CheckForUpdate().Wait());
}
}
}
[Fact]
public void WhenReleasesFileDoesntExistThrowACustomError()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
var fixture = new UpdateManager(tempDir, "MyAppName", FrameworkVersion.Net40);
using (fixture) {
Assert.Throws<SquirrelConfigurationException>(
() => fixture.CheckForUpdate().Wait());
}
}
}
[Fact]
public void WhenReleasesFileIsBlankReturnNull()
{
string tempDir;
using (Utility.WithTempDirectory(out tempDir)) {
var fixture = new UpdateManager(tempDir, "MyAppName", FrameworkVersion.Net40);
File.WriteAllText(Path.Combine(tempDir, "RELEASES"), "");
using (fixture) {
Assert.Null(fixture.CheckForUpdate().Wait());
}
}
}
[Fact]
public void WhenUrlTimesOutReturnNull()
{
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net45, null, null, new TimingOutUrlDownloader());
var updateInfo = fixture.CheckForUpdate().Wait();
Assert.Null(updateInfo);
}
[Fact]
public void WhenUrlResultsInWebExceptionReturnNull()
{
// This should result in a WebException (which gets caught) unless you can actually access http://lol
var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net45);
var updateInfo = fixture.CheckForUpdate().Wait();
Assert.Null(updateInfo);
}
}
}
}