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);
                }
            }
예제 #2
0
        public MainWindowViewModel()
        {
            var noneInFlight = new BehaviorSubject<bool>(false);
            var updateManager = default(UpdateManager);

            this.WhenAny(x => x.UpdatePath, x => x.Value)
                .Where(x => !String.IsNullOrWhiteSpace(x))
                .Throttle(TimeSpan.FromMilliseconds(700), RxApp.DeferredScheduler)
                .Subscribe(x => {
                    if (updateManager != null)  updateManager.Dispose();
                    updateManager = new UpdateManager(UpdatePath, "SampleUpdatingApp", FrameworkVersion.Net40);
                });

            CheckForUpdate = new ReactiveAsyncCommand(noneInFlight);
            CheckForUpdate.RegisterAsyncObservable(_ => updateManager.CheckForUpdate())
                .Subscribe(x => { UpdateInfo = x; DownloadedUpdateInfo = null; });

            DownloadReleases = new ReactiveAsyncCommand(noneInFlight.Where(_ => UpdateInfo != null));
            DownloadReleases.RegisterAsyncObservable(_ => updateManager.DownloadReleases(UpdateInfo.ReleasesToApply))
                .Subscribe(_ => DownloadedUpdateInfo = UpdateInfo);

            ApplyReleases = new ReactiveAsyncCommand(noneInFlight.Where(_ => DownloadedUpdateInfo != null));
            ApplyReleases.RegisterAsyncObservable(_ => updateManager.ApplyReleases(DownloadedUpdateInfo));

            Observable.CombineLatest(
                CheckForUpdate.ItemsInflight.StartWith(0),
                DownloadReleases.ItemsInflight.StartWith(0),
                ApplyReleases.ItemsInflight.StartWith(0),
                this.WhenAny(x => x.UpdatePath, _ => 0),
                (a, b, c, _) => a + b + c
            ).Select(x => x == 0 && UpdatePath != null).Multicast(noneInFlight).Connect();
        }
예제 #3
0
        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());
        }
예제 #4
0
        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);
        }
            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);
                }
            }
예제 #6
0
        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();
            }
        }
        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);
                });
            }
        }
예제 #8
0
        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());   
            }
        }
예제 #9
0
        public void ApplyMultipleDeltaPackagesGeneratesCorrectHash()
        {
            var firstRelease = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.0.0-full.nupkg"), true);
            var secondRelease = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.1.0-full.nupkg"), true);
            var thirdRelease = new ReleasePackage(IntegrationTestHelper.GetPath("fixtures", "SquirrelDesktopDemo-1.2.0-full.nupkg"), true);

            string installDir, releasesDir;
            using(Utility.WithTempDirectory(out releasesDir))
            using (IntegrationTestHelper.WithFakeAlreadyInstalledApp("InstalledSquirrelDesktopDemo-1.0.0.zip", out installDir)) {

                var firstDelta = Path.Combine(releasesDir, "SquirrelDesktopDemo-1.1.0-delta.nupkg");
                var secondDelta = Path.Combine(releasesDir, "SquirrelDesktopDemo-1.2.0-delta.nupkg");

            
                new[] { firstRelease, secondRelease, thirdRelease }
                .ForEach(file =>
                {
                    var packageFile = file.ReleasePackageFile;
                    var fileName = Path.GetFileName(packageFile);
                    File.Copy(packageFile, Path.Combine(releasesDir, fileName));
                });

                var deltaBuilder = new DeltaPackageBuilder();
                deltaBuilder.CreateDeltaPackage(firstRelease, secondRelease, firstDelta);
                deltaBuilder.CreateDeltaPackage(secondRelease, thirdRelease, secondDelta);

                ReleaseEntry.BuildReleasesFile(releasesDir);

                var updateManager = new UpdateManager(
                    releasesDir, "ShimmerDesktopDemo", FrameworkVersion.Net40, installDir);

                using (updateManager) {
                    var updateInfo = updateManager.CheckForUpdate().First();

                    Assert.Equal(2, updateInfo.ReleasesToApply.Count());

                    updateManager.DownloadReleases(updateInfo.ReleasesToApply).Wait();
                    updateManager.ApplyReleases(updateInfo).Wait();
                }

                string referenceDir;
                using (IntegrationTestHelper.WithFakeAlreadyInstalledApp("InstalledSquirrelDesktopDemo-1.2.0.zip", out referenceDir)) {

                    var referenceVersion = Path.Combine(referenceDir, "ShimmerDesktopDemo", "app-1.2.0");
                    var installVersion = Path.Combine(installDir, "ShimmerDesktopDemo", "app-1.2.0");

                    var referenceFiles = Directory.GetFiles(referenceVersion);
                    var actualFiles = Directory.GetFiles(installVersion);

                    Assert.Equal(referenceFiles.Count(), actualFiles.Count());

                    var invalidFiles =
                        Enumerable.Zip(referenceFiles, actualFiles,
                        (reference, actual) => {

                            var refSha = Utility.CalculateFileSHA1(reference);
                            var actualSha = Utility.CalculateFileSHA1(actual);

                            return new { File = actual, Result = refSha == actualSha };
                        })
                        .Where(c => !c.Result).ToArray();

                    Assert.Empty(invalidFiles);
                }
            }
        }
예제 #10
0
        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);
                });
            }
        }
예제 #11
0
        private IObservable<UpdateAvailableNotification> CheckForUpdates()
        {
            return Observable.Create<UpdateAvailableNotification>(async obs =>
            {
                string updateUrl = AppModel.GetRegistrySetting("UpdateUrl");
                Log.DebugFormat("UpdateUrl = {0}", updateUrl);
                using (var updateManager = new UpdateManager(updateUrl ?? @"http://bradleygrainger.com/GitBlame/download", "GitBlame", FrameworkVersion.Net45))
                {
                    try
                    {
                        UpdateInfo updateInfo = await updateManager.CheckForUpdate();
                        var releases = updateInfo == null ? new List<ReleaseEntry>() : updateInfo.ReleasesToApply.ToList();
                        if (updateInfo == null)
                            Log.Info("CheckForUpdate returned (null)");
                        else
                            Log.InfoFormat("CheckForUpdate: Current=({0}), Future=({1}), {2} ReleasesToApply", ToLog(updateInfo.CurrentlyInstalledVersion), ToLog(updateInfo.FutureReleaseEntry), releases.Count);

                        if (releases.Count != 0)
                        {
                            await updateManager.DownloadReleases(releases);
                            Log.Info("Downloaded releases");
                            var results = await updateManager.ApplyReleases(updateInfo);
                            Log.InfoFormat("ApplyReleases: {0}", string.Join(", ", results));

                            if (results.Any())
                            {
                                string newPath = results[0];
                                VisualStudioIntegration.ReintegrateWithVisualStudio(newPath);
                                obs.OnNext(new UpdateAvailableNotification(newPath));
                            }
                        }
                    }
                    catch (InvalidOperationException ex)
                    {
                        // Squirrel throws an InvalidOperationException (wrapping the underlying exception) if anything goes wrong
                        Log.ErrorFormat("CheckForUpdates failed: {0}", ex, ex.Message);
                    }
                    catch (TimeoutException ex)
                    {
                        // Failed to check for updates; try again the next time the app is run
                        Log.ErrorFormat("CheckForUpdates timed out: {0}", ex, ex.Message);
                    }
                }
                obs.OnCompleted();
            });
        }
예제 #12
0
        static int Main(string[] args)
        {
            var command = "";
            var target = "";
            var appName = default(string);
            var showHelp = false;

            var opts = new OptionSet() {
                { "c|command=", "One of 'check' or 'update' to return the latest update information, or to perform the update", v => command = v },
                { "t|update-target=", "The URL or directory to download updates from", v => target = v },
                { "n|app-name=", "(Optional) The name of the application, only necessary if updater.exe isn't in the install directory", v => appName = v},
                { "h|help", "Show this message and exit", v => showHelp = v != null },
            };

            opts.Parse(args);

            if (!new[] { "check", "update", "install", }.Any(x => command.ToLowerInvariant() == x)) {
                Console.Error.WriteLine("Command must be either 'check' or 'update'");
                showHelp = true;
            }

            if (!Directory.Exists(target) && !File.Exists(target) && !isAUrl(target)) {
                Console.Error.WriteLine("Target must be either a directory or a URL to check for updates");
                showHelp = true;
            }

            if (showHelp) {
                Console.WriteLine("\nSquirrel.Updater.exe - Check for updates or update an application");
                Console.WriteLine(@"Usage: Squirrel.Updater.exe [options]");

                Console.WriteLine("Options:");
                foreach(var v in opts) {
                    if (v.GetNames().Length != 2) {
                        Console.WriteLine("  --{0} - {1}", v.GetNames()[0], v.Description);
                    } else {
                        Console.WriteLine("  -{0}/--{1} - {2}", v.GetNames()[0], v.GetNames()[1], v.Description);
                    }
                }

                return 0;
            }

            appName = appName ?? determineAppName();
            using (var mgr = new UpdateManager(target, appName, FrameworkVersion.Net40)) {
                if (command.ToLowerInvariant() == "check") {
                    var updateInfo = default(UpdateInfo);
                    try {
                        updateInfo = mgr.CheckForUpdate().First();

                        if (updateInfo.ReleasesToApply.Count > 0) {
                            mgr.DownloadReleases(updateInfo.ReleasesToApply).First();
                        }
                    } catch (Exception ex) {
                        writeJsonForException(ex, "Failed to check for updates");
                        return -1;
                    }

                    var releaseNotes = new Dictionary<ReleaseEntry, string>();

                    try {
                        releaseNotes = (updateInfo.ReleasesToApply.Count > 0) ? updateInfo.FetchReleaseNotes() : releaseNotes;
                    } catch (Exception ex) {
                        // TODO: Find a way to log this
                    }

                    Console.WriteLine(JsonConvert.SerializeObject(new {
                        UpdateInfo = updateInfo,
                        ReleaseNotes = releaseNotes,
                    }));

                    return 0;
                }

                if (command.ToLowerInvariant() == "update") {
                    var result = default(ReleaseEntry);
                    try {
                        result = mgr.UpdateAppAsync().Result;
                    } catch (Exception ex) {
                        writeJsonForException(ex, "Failed to update application");
                        return -1;
                    }

                    Console.WriteLine(JsonConvert.SerializeObject(result));
                    return 0;
                }

                if (command.ToLowerInvariant() == "install") {
                    var targetRelease = ReleaseEntry.GenerateFromFile(target);
                    mgr.ApplyReleases(UpdateInfo.Create(null, new[] { targetRelease }, Path.GetDirectoryName(target), FrameworkVersion.Net40)).First();
                    return 0;
                }
            }

            throw new Exception("How even did we get here?");
        }
예제 #13
0
        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));
            }
        }
예제 #14
0
        public IObservable<Unit> ExecuteUninstall(Version version = null)
        {
            var updateManager = new UpdateManager("http://lol", BundledRelease.PackageName, FrameworkVersion.Net40, TargetRootDirectory);

            return updateManager.FullUninstall(version)
                .ObserveOn(RxApp.DeferredScheduler)
                .Log(this, "Full uninstall")
                .Finally(updateManager.Dispose);
        }
예제 #15
0
            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);
            }
예제 #16
0
        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);
                });
            }
        }
예제 #17
0
            public void WhenUrlTimesOutReturnNull()
            {
                var fixture = new UpdateManager("http://lol", "theApp", FrameworkVersion.Net45, null, null, new TimingOutUrlDownloader());

                var updateInfo = fixture.CheckForUpdate().Wait();

                Assert.Null(updateInfo);
            }
예제 #18
0
            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());
                    }
                }
            }
예제 #19
0
            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());
                    }
                }
            }
예제 #20
0
            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());
                    }
                }
            }
예제 #21
0
            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);
                    }
                }

            }
예제 #22
0
        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");
            }
        }
예제 #23
0
        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();
            }
        }