Пример #1
0
 public void MatchingFolder()
 {
     using (var folder = new TemporaryFolder())
     {
         Assert.IsTrue(filter.IsMatch(folder.DirectoryInfo, environment));
     }
 }
 public void NewFolder_IsMatch_ReturnsFalse()
 {
     using (var folder = new TemporaryFolder())
     {
         folder.DirectoryInfo.LastWriteTime = DateTime.Now;
         Assert.IsFalse(filter.IsMatch(folder.DirectoryInfo, environment));
     }
 }
 public void OldFolder_IsMatch_ReturnsTrue()
 {
     using (var folder = new TemporaryFolder())
     {
         folder.DirectoryInfo.LastWriteTime = DateTime.Now.Subtract(TimeSpan.FromDays(2));
         Assert.IsTrue(filter.IsMatch(folder.DirectoryInfo, environment));
     }
 }
Пример #4
0
 public void NonMatchingFolder()
 {
     using (var folder = new TemporaryFolder())
     {
         using (TemporaryFile file1 = folder.CreateFile(), file2 = folder.CreateFile())
         {
             Assert.IsFalse(filter.IsMatch(folder.DirectoryInfo, environment));
         }
     }
 }
 public void MatchingFolder()
 {
     using (var folder = new TemporaryFolder())
     {
         using (TemporaryFile file1 = folder.CreateFile(), file2 = folder.CreateFile())
         {
             file1.Contents = "01234";
             file2.Contents = "56789";
             Assert.IsTrue(filter.IsMatch(folder.DirectoryInfo, environment));
         }
     }
 }
Пример #6
0
        public void FileIfExistsCancel()
        {
            using (TemporaryFolder folder1 = new TemporaryFolder(), folder2 = new TemporaryFolder())
            {
                var file1 = folder1.CreateFile();
                var file2 = folder2.CreateFile(file1.Name);

                var rule = new MoveRule
                {
                    Destination = folder2.Path,
                    IfExists = MoveRule.IfExistsMode.Cancel
                };

                rule.Apply(file1.FileInfo, environment);

                Assert.IsTrue(folder1.Files.Any(x => x.Name == file1.Name));
                Assert.AreEqual(1, folder2.Files.Count());
            }
        }
Пример #7
0
        public void FileIfExistsDelete()
        {
            using (TemporaryFolder folder = new TemporaryFolder())
            {
                var file1 = folder.CreateFile();
                var file2 = folder.CreateFile();

                var originalName = file1.Name;
                var newName = file2.Name;

                var rule = new RenameRule
                {
                    Name = newName,
                    IfExists = RenameRule.IfExistsMode.Delete
                };

                rule.Apply(file1.FileInfo, environment);

                Assert.IsFalse(folder.Files.Any(x => x.Name == originalName));
                Assert.IsTrue(folder.Files.Any(x => x.Name == newName));
                Assert.AreEqual(1, folder.Files.Count());
            }
        }
Пример #8
0
        /// <summary>
        /// Warning, if the book already exists in the location, this is going to delete it an over-write it. So it's up to the caller to check the sanity of that.
        /// </summary>
        /// <param name="storageKeyOfBookFolder"></param>
        public string DownloadBook(string storageKeyOfBookFolder, string pathToDestinationParentDirectory, ProgressDialog downloadProgress = null)
        {
            //TODO tell it not to download pdfs. Those are just in there for previewing purposes, we don't need to get them now that we're getting the real thing

            //review: should we instead save to a newly created folder so that we don't have to worry about the
            //other folder existing already? Todo: add a test for that first.

            if (!GetBookExists(storageKeyOfBookFolder))
            {
                throw new DirectoryNotFoundException("The book we tried to download is no longer in the BloomLibrary");
            }

            using (var tempDestination =
                       new TemporaryFolder("BloomDownloadStaging " + storageKeyOfBookFolder + " " + Guid.NewGuid()))
            {
                var request = new TransferUtilityDownloadDirectoryRequest()
                {
                    BucketName     = _bucketName,
                    S3Directory    = storageKeyOfBookFolder,
                    LocalDirectory = tempDestination.FolderPath
                };
                int downloaded      = 0;
                int initialProgress = 0;
                if (downloadProgress != null)
                {
                    downloadProgress.Invoke((Action)(() =>
                    {
                        downloadProgress.Progress++;                         // count getting set up as one step.
                        initialProgress = downloadProgress.Progress;         // might be one more step done, downloading order
                    }));
                }
                int total = 14;                 // arbitrary (typical minimum files in project)
                request.DownloadedDirectoryProgressEvent += delegate(object sender, DownloadDirectoryProgressArgs args)
                {
                    int progressMax     = initialProgress + args.TotalNumberOfFiles;
                    int currentProgress = initialProgress + args.NumberOfFilesDownloaded;
                    if (downloadProgress != null && (progressMax != total || currentProgress != downloaded))
                    {
                        total      = progressMax;
                        downloaded = currentProgress;
                        // We only want to invoke if something really changed.
                        downloadProgress.Invoke((Action)(() =>
                        {
                            downloadProgress.ProgressRangeMaximum = progressMax;                             // probably only changes the first time
                            downloadProgress.Progress = currentProgress;
                        }));
                    }
                };
                _transferUtility.DownloadDirectory(request);

                //look inside the wrapper that we got

                var children = Directory.GetDirectories(tempDestination.FolderPath);
                if (children.Length != 1)
                {
                    throw new ApplicationException(
                              string.Format("Bloom expected to find a single directory in {0}, but instead there were {1}",
                                            tempDestination.FolderPath, children.Length));
                }
                var destinationPath = Path.Combine(pathToDestinationParentDirectory, Path.GetFileName(children[0]));

                //clear out anything exisitng on our target
                if (Directory.Exists(destinationPath))
                {
                    Directory.Delete(destinationPath, true);
                }

                //if we're on the same volume, we can just move it. Else copy it.
                // It's important that books appear as nearly complete as possible, because a file watcher will very soon add the new
                // book to the list of downloaded books the user can make new ones from, once it appears in the target directory.
                if (Directory.GetDirectoryRoot(pathToDestinationParentDirectory) == Directory.GetDirectoryRoot(tempDestination.FolderPath))
                {
                    Directory.Move(children[0], destinationPath);
                }
                else
                {
                    CopyDirectory(children[0], destinationPath);
                }
                return(destinationPath);
            }
        }
Пример #9
0
 public override void SetUp()
 {
     _tempFolder         = new TemporaryFolder("LiftLexEntryRepositoryDeleteItemTransitionTests");
     _persistedFilePath  = _tempFolder.GetNewTempFile(false);
     DataMapperUnderTest = new LiftLexEntryRepository(_persistedFilePath.Path);
 }
Пример #10
0
 private Project CreateProject(TemporaryFolder parent)
 {
     return(new Project(parent.Combine("foo", "foo." + Project.ProjectSettingsFileExtension),
                        GetSessionRepo, _projectContext.ResolveForTests <SessionFileType>()));
 }
Пример #11
0
 public void Setup()
 {
     _parentFolder = new TemporaryFolder("projectTest");
 }
Пример #12
0
        public void UpdateToLongHashOnNonEmptyRepoReturns_UpdateResults_Success()
        {
            using (var testRoot = new TemporaryFolder("RepositoryTests"))
            {
                var progress = new NullProgress();
                HgRepository.CreateRepositoryInExistingDir(testRoot.Path, progress);
                // fileX and fileXRev are zero based indexing, since those local commit numbers in Hg are zero based indexing.
                using (var file0 = testRoot.GetNewTempFile(true))
                {
                    var repo = new HgRepository(testRoot.Path, new NullProgress());

                    repo.AddAndCheckinFile(file0.Path);
                    var file0Rev = repo.GetRevisionWorkingSetIsBasedOn();
                    using (var file1 = testRoot.GetNewTempFile(true))
                    {
                        // On same branch.
                        repo.AddAndCheckinFile(file1.Path);
                        var file1Rev = repo.GetRevisionWorkingSetIsBasedOn();
                        using (var file2 = testRoot.GetNewTempFile(true))
                        {
                            // Make new branch.
                            repo.BranchingHelper.Branch(progress, "newbranch");
                            repo.AddAndCheckinFile(file2.Path);
                            var file2Rev = repo.GetRevisionWorkingSetIsBasedOn();

                            // Round 1: update from rev 0 to rev 2.
                            // Switch back to rev 0, using old method.
                            repo.Update("0");
                            var testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            // It did move.
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file0Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.
                            // SUT
                            Assert.That(repo.UpdateToLongHash(file2Rev.Number.LongHash), Is.EqualTo(HgRepository.UpdateResults.Success));
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file2Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo("newbranch"));

                            // Round 2: update from rev 1 to rev 2.
                            // Set up for another pass to update to file2Rev from file3Rev
                            // Switch back to rev 1 (default branch), using old method.
                            repo.Update("1");
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            // It did move.
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file1Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.
                            // SUT
                            Assert.That(repo.UpdateToLongHash(file2Rev.Number.LongHash), Is.EqualTo(HgRepository.UpdateResults.Success));
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file2Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo("newbranch"));

                            // Round 3: downgrade from rev 2 to rev 0.
                            // Set up for another pass to update to file0Rev from file2Rev
                            // Switch back to rev 2 (newbranch branch), using old method.
                            repo.Update("2");
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            // It did move.
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file2Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo("newbranch"));
                            // SUT
                            Assert.That(repo.UpdateToLongHash(file0Rev.Number.LongHash), Is.EqualTo(HgRepository.UpdateResults.Success));
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file0Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.

                            // Round 4: downgrade from rev 2 to rev 1.
                            // Set up for another pass to update to file2Rev from file1Rev
                            // Switch back to rev 2 (newbranch branch), using old method.
                            repo.Update("2");
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            // It did move.
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file2Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo("newbranch"));
                            // SUT
                            Assert.That(repo.UpdateToLongHash(file1Rev.Number.LongHash), Is.EqualTo(HgRepository.UpdateResults.Success));
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file1Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.

                            // Round 5: downgrade from rev 1 to rev 0.
                            // Set up for another pass to update to file0Rev from file1Rev
                            // Switch back to rev 0 (default branch), using old method.
                            repo.Update("1");
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            // It did move.
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file1Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.
                            // SUT
                            Assert.That(repo.UpdateToLongHash(file0Rev.Number.LongHash), Is.EqualTo(HgRepository.UpdateResults.Success));
                            testRev = repo.GetRevisionWorkingSetIsBasedOn();
                            Assert.That(testRev.Number.LongHash, Is.EqualTo(file0Rev.Number.LongHash));
                            Assert.That(testRev.Branch, Is.EqualTo(string.Empty));                             // default branch returns string.Empty in mercurial.
                        }
                    }
                }
            }
        }
Пример #13
0
 public void Setup()
 {
     _fixtureFolder = new TemporaryFolder("BloomBookStorageTest");
     _folder        = new TemporaryFolder(_fixtureFolder, "theBook");
 }
Пример #14
0
        /// <summary>
        /// Warning, if the book already exists in the location, this is going to delete it an over-write it. So it's up to the caller to check the sanity of that.
        /// </summary>
        /// <param name="storageKeyOfBookFolder"></param>
        public string DownloadBook(string bucketName, string storageKeyOfBookFolder, string pathToDestinationParentDirectory,
                                   IProgressDialog downloadProgress = null)
        {
            //review: should we instead save to a newly created folder so that we don't have to worry about the
            //other folder existing already? Todo: add a test for that first.

            // We need to download individual files to avoid downloading unwanted files (PDFs and thumbs.db to
            // be specific).  See https://silbloom.myjetbrains.com/youtrack/issue/BL-2312.  So we need the list
            // of items, not just the count.
            var matching   = GetMatchingItems(bucketName, storageKeyOfBookFolder);
            var totalItems = CountDesiredFiles(matching);

            if (totalItems == 0)
            {
                throw new DirectoryNotFoundException("The book we tried to download is no longer in the BloomLibrary");
            }

            Debug.Assert(matching.S3Objects[0].Key.StartsWith(storageKeyOfBookFolder + "/"));

            // Get the top-level directory name of the book from the first object key.
            var bookFolderName = matching.S3Objects[0].Key.Substring(storageKeyOfBookFolder.Length + 1);

            while (bookFolderName.Contains("/"))
            {
                bookFolderName = Path.GetDirectoryName(bookFolderName);
            }

            // Amazon.S3 appears to truncate titles at 50 characters when building directory and filenames.  This means
            // that relative paths can be as long as 117 characters (2 * 50 + 2 for slashes + 15 for .BloomBookOrder).
            // So our temporary folder must be no more than 140 characters (allow some margin) since paths can be a
            // maximum of 260 characters in Windows.  (More margin than that may be needed because there's no guarantee
            // that image filenames are no longer than 65 characters.)  See https://jira.sil.org/browse/BL-1160.
            using (var tempDestination = new TemporaryFolder("BDS_" + Guid.NewGuid()))
            {
                var tempDirectory = Path.Combine(tempDestination.FolderPath, bookFolderName);
                if (downloadProgress != null)
                {
                    downloadProgress.Invoke((Action)(() => { downloadProgress.ProgressRangeMaximum = totalItems; }));
                }
                int booksDownloaded = 0;
                using (var transferUtility = new TransferUtility(_amazonS3))
                {
                    for (int i = 0; i < matching.S3Objects.Count; ++i)
                    {
                        var objKey = matching.S3Objects[i].Key;
                        if (AvoidThisFile(objKey))
                        {
                            continue;
                        }
                        // Removing the book's prefix from the object key, then using the remainder of the key
                        // in the filepath allows for nested subdirectories.
                        var filepath = objKey.Substring(storageKeyOfBookFolder.Length + 1);
                        // Download this file then bump progress.
                        var req = new TransferUtilityDownloadRequest()
                        {
                            BucketName = bucketName,
                            Key        = objKey,
                            FilePath   = Path.Combine(tempDestination.FolderPath, filepath)
                        };
                        transferUtility.Download(req);
                        ++booksDownloaded;
                        if (downloadProgress != null)
                        {
                            downloadProgress.Invoke((Action)(() => { downloadProgress.Progress = booksDownloaded; }));
                        }
                    }
                    var destinationPath = Path.Combine(pathToDestinationParentDirectory, bookFolderName);

                    //clear out anything existing on our target
                    var didDelete = false;
                    if (Directory.Exists(destinationPath))
                    {
                        try
                        {
                            SIL.IO.RobustIO.DeleteDirectory(destinationPath, true);
                            didDelete = true;
                        }
                        catch (IOException)
                        {
                            // can't delete it...see if we can copy into it.
                        }
                    }

                    //if we're on the same volume, we can just move it. Else copy it.
                    // It's important that books appear as nearly complete as possible, because a file watcher will very soon add the new
                    // book to the list of downloaded books the user can make new ones from, once it appears in the target directory.
                    bool done = false;
                    if (didDelete && PathUtilities.PathsAreOnSameVolume(pathToDestinationParentDirectory, tempDirectory))
                    {
                        try
                        {
                            SIL.IO.RobustIO.MoveDirectory(tempDirectory, destinationPath);
                            done = true;
                        }
                        catch (IOException)
                        {
                            // If moving didn't work we'll just try copying
                        }
                        catch (UnauthorizedAccessException)
                        {
                        }
                    }
                    if (!done)
                    {
                        done = CopyDirectory(tempDirectory, destinationPath);
                    }
                    if (!done)
                    {
                        var msg = LocalizationManager.GetString("Download.CopyFailed",
                                                                "Bloom downloaded the book but had problems making it available in Bloom. Please restart your computer and try again. If you get this message again, please click the 'Details' button and report the problem to the Bloom developers");
                        // The exception doesn't add much useful information but it triggers a version of the dialog with a Details button
                        // that leads to the yellow box and an easy way to send the report.
                        ErrorReport.NotifyUserOfProblem(new ApplicationException("File Copy problem"), msg);
                    }
                    return(destinationPath);
                }
            }
        }
Пример #15
0
        private bool AddLoaderFile(
            TemporaryFolder temporaryFolder,
            ApplicationMetadata applicationMetadata,
            ZipArchive zipArchive,
            SemanticVersion newVersion,
            string applicationLocation,
            OSPlatform?intendedOs      = null,
            SemanticVersion?oldVersion = null,
            string?outputLocation      = null)
        {
            //TODO: See why this is making another .shasum file (but working)
            using var loaderLocation = temporaryFolder.CreateTemporaryFile(applicationMetadata.ApplicationName + ".exe");
            // ReSharper disable once LocalFunctionHidesMethod
            bool AddFile() => BinaryCreator.AddFile(
                zipArchive,
                loaderLocation.GetStream(FileMode.Open),
                applicationMetadata.ApplicationName + ".exe.load",
                false);

            //TODO: Grab metadata from .exe and drop it into Loader
            var iconLocation = Path.Combine(applicationLocation, "app.ico");

            iconLocation = File.Exists(iconLocation) ? iconLocation : null;

            var successful = LoaderCreator.CreateLoader(
                temporaryFolder,
                $"{newVersion.GetApplicationFolder()}\\{applicationMetadata.ApplicationName}.exe",
                iconLocation,
                loaderLocation.Location,
                applicationMetadata.ApplicationName,
                intendedOs);

            if (successful != LoadCreateStatus.Successful)
            {
                var canContinue = successful == LoadCreateStatus.UnableToCreate;
                _logger.Error("We wasn't able to create loader! (Going to fail file creation?: {0})", canContinue);
                return(canContinue);
            }
            if (oldVersion == null || !Directory.Exists(outputLocation))
            {
                return(AddFile());
            }

            //If we get here then we might also have the old loader, try to diff by using it
            foreach (var file in Directory.EnumerateFiles(outputLocation !, "*" + Extension))
            {
                if (string.IsNullOrWhiteSpace(file))
                {
                    _logger.Warning("We somehow got an entry for {0} which was nothing", outputLocation);
                    continue;
                }

                /*Don't try it with delta file, more then likely going to
                 * have diff loader itself and we can't work with that*/
                var fileName = Path.GetFileNameWithoutExtension(file);
                if (fileName.EndsWith("-delta") ||
                    fileName.ToVersion() != oldVersion)
                {
                    continue;
                }

                Stream?    stream = null;
                ZipArchive fileArch;
                try
                {
                    stream   = File.OpenRead(file);
                    fileArch = new ZipArchive(stream, ZipArchiveMode.Read);
                }
                catch (Exception e)
                {
                    stream?.Dispose();
                    _logger.Error(e);
                    continue;
                }

                //We want to grab the loader file
                var loaderFileIndex = fileArch.Entries.IndexOf(x => x?.Name == applicationMetadata.ApplicationName + ".exe.load");
                if (loaderFileIndex == -1)
                {
                    fileArch.Dispose();
                    continue;
                }

                var fileEntry = fileArch.Entries[loaderFileIndex];
                using var tmpFile = temporaryFolder.CreateTemporaryFile(Path.GetFileNameWithoutExtension(fileEntry.Name));
                fileEntry.ExtractToFile(tmpFile.Location, true);

                var deltaSuccessful =
                    AddDeltaFile(temporaryFolder,
                                 zipArchive,
                                 tmpFile.Location,
                                 loaderLocation.Location,
                                 extensionEnd: "load");
                if (!deltaSuccessful)
                {
                    _logger.Warning("Wasn't able to diff loader, just going to add the load in as normal");
                }
                fileArch.Dispose();
                return(deltaSuccessful || AddFile());
            }

            //If we get here then we can't do any kind of diff logic
            return(AddFile());
        }
Пример #16
0
        public bool CreateDeltaPackage(
            ApplicationMetadata applicationMetadata,
            string newVersionLocation,
            SemanticVersion newVersion,
            string baseVersionLocation,
            SemanticVersion oldVersion,
            string outputFolder,
            string deltaUpdateLocation,
            OSPlatform?intendedOs    = null,
            Action <double>?progress = null)
        {
            if (!Directory.Exists(newVersionLocation) ||
                !Directory.Exists(baseVersionLocation))
            {
                _logger.Error("One of the folders don't exist, can't create delta update....");
                return(false);
            }

            _logger.Debug("Creating delta file");
            var zipArchive = CreateZipArchive(deltaUpdateLocation);
            var tempFolder = new TemporaryFolder(applicationMetadata.TempFolder);

            void Cleanup()
            {
                lock (zipArchive)
                {
                    zipArchive.Dispose();
                }
                tempFolder.Dispose();
                progress?.Invoke(1);
            }

            //Get all the files that are in the new version (Removing the Path so we only have the relative path of the file)
            var newVersionFiles = Directory.EnumerateFiles(newVersionLocation, "*", SearchOption.AllDirectories)
                                  .RemovePath(newVersionLocation).ToArray();

            //and get the files from the old version
            var baseVersionFiles = Directory.EnumerateFiles(baseVersionLocation, "*", SearchOption.AllDirectories)
                                   .RemovePath(baseVersionLocation).ToArray();

            //Find any files that are in both version and process them based on if they had any changes
            var sameFiles = newVersionFiles.Where(x => baseVersionFiles.Contains(x)).ToArray();
            var newFiles  = newVersionFiles.Where(x => !sameFiles.Contains(x)).ToArray();

            var progressReport = new ProgressReport(newFiles.Length + sameFiles.Length, progress);
            var deltaFiles     = new List <string>(sameFiles.Length);

            //First process any files that didn't change, don't even count them in the progress as it will be quick af
            _logger.Information("Processing files that are in both versions");
            foreach (var maybeDeltaFile in sameFiles)
            {
                _logger.Debug("Processing possible delta file {0}", maybeDeltaFile);
                var newFileLocation = Path.Combine(newVersionLocation, maybeDeltaFile);

                /*See if we got a delta file, if so then store it for
                 * processing after files that haven't changed*/
                if (IsDeltaFile(Path.Combine(baseVersionLocation, maybeDeltaFile),
                                newFileLocation))
                {
                    deltaFiles.Add(maybeDeltaFile);
                    continue;
                }

                //Add a pointer to the file that hasn't changed
                _logger.Debug("{0} hasn't changed, processing as unchanged file", maybeDeltaFile);

                using var fileStream = File.OpenRead(newFileLocation);
                if (AddSameFile(zipArchive, maybeDeltaFile, SHA256Util.CreateSHA256Hash(fileStream)))
                {
                    progressReport.ProcessedFile();
                    continue;
                }
                _logger.Warning("We wasn't able to add {0} as a file that was unchanged, adding as a \"new\" file",
                                maybeDeltaFile);

                //We wasn't able to add the file as a pointer, try to add it as a new file
                if (!AddNewFile(zipArchive, fileStream, maybeDeltaFile))
                {
                    //Hard bail if we can't even do that
                    _logger.Error("Wasn't able to process {0} as a new file as well, bailing", maybeDeltaFile);
                    Cleanup();
                    return(false);
                }
                progressReport.ProcessedFile();
            }

            //TODO: add "moved files"
            //Now process files that was added into the new version
            _logger.Information("Processing files that only exist in the new version");
            foreach (var newFile in newFiles)
            {
                _logger.Debug("Processing new file {0}", newFile);

                //Process new file
                using var fileStream = File.OpenRead(Path.Combine(newVersionLocation, newFile));
                if (AddNewFile(zipArchive, fileStream, newFile))
                {
                    progressReport.ProcessedFile();
                    continue;
                }

                //if we can't add it then hard fail, can't do anything to save this
                _logger.Error("Wasn't able to process new file, bailing");
                Cleanup();
                return(false);
            }

            //Now process files that changed
            var result = Parallel.ForEach(deltaFiles, (deltaFile, state) =>
            {
                var deltaFileLocation = Path.Combine(newVersionLocation, deltaFile);
                _logger.Debug("Processing changed file {0}", deltaFile);

                //Try to add the file as a delta file
                if (AddDeltaFile(tempFolder,
                                 zipArchive,
                                 Path.Combine(baseVersionLocation, deltaFile),
                                 deltaFileLocation,
                                 intendedOs,
                                 (pro) => progressReport.PartialProcessedFile(pro)))
                {
                    progressReport.ProcessedFile();
                    return;
                }

                //If we can't make the file as a delta file try to create it as a "new" file
                _logger.Warning("Wasn't able to make delta file, adding file as \"new\" file");
                using var fileStream = File.OpenRead(Path.Combine(newVersionLocation, deltaFileLocation));
                if (AddNewFile(zipArchive, fileStream, deltaFile))
                {
                    progressReport.ProcessedFile();
                    return;
                }

                //Hard bail if we can't even do that
                _logger.Error("Wasn't able to process file as a new file, bailing");
                Cleanup();
                state.Break();
            });

            //This will return false if something failed
            if (!result.IsCompleted)
            {
                return(false);
            }

            if (ShouldMakeLoader &&
                !AddLoaderFile(
                    tempFolder,
                    applicationMetadata,
                    zipArchive,
                    newVersion,
                    newVersionLocation,
                    intendedOs,
                    oldVersion,
                    outputFolder))
            {
                _logger.Error("Wasn't able to create loader for this application");
                Cleanup();
                return(false);
            }
            progressReport.ProcessedFile();

            //We have created the delta file if we get here, do cleanup and then report as success!
            _logger.Information("We are done with creating the delta file, cleaning up");
            Cleanup();
            return(true);
        }
Пример #17
0
 public void Setup()
 {
     _parentFolder = new TemporaryFolder("componentFileTest");
     _fileTypes    = new List <FileType>();
     _fileTypes.Add(new AnnotationFileType(null, null));
 }
Пример #18
0
 public override void SetUp()
 {
     _tempFolder         = new TemporaryFolder("LexEntryRepositoryDeleteAllItemsTransitionTests");
     _persistedFilePath  = _tempFolder.GetTemporaryFile();
     DataMapperUnderTest = new LexEntryRepository(_persistedFilePath);
 }
Пример #19
0
        /// <summary>
        /// Creates a delta file and then adds it the <see cref="ZipArchive"/>
        /// </summary>
        /// <param name="tempFolder">Where the temp folder is located</param>
        /// <param name="zipArchive"><see cref="ZipArchive"/> to add the file too</param>
        /// <param name="baseFileLocation">Old file</param>
        /// <param name="newFileLocation">New file</param>
        /// <param name="intendedOs">What OS this delta file will be intended for</param>
        /// <param name="progress">Progress of creating delta file (If possible)</param>
        /// <param name="extensionEnd">What to add onto the end of the extension (If needed)</param>
        /// <returns>If we was able to create the delta file</returns>
        private bool AddDeltaFile(
            TemporaryFolder tempFolder,
            ZipArchive zipArchive,
            string baseFileLocation,
            string newFileLocation,
            OSPlatform?intendedOs    = null,
            Action <double>?progress = null,
            string?extensionEnd      = null)
        {
            //Create where the delta file can be stored to grab once made
            using var tmpDeltaFile = tempFolder.CreateTemporaryFile();

            //Try to create diff file, outputting extension (and maybe a stream) based on what was used to make it
            if (!DeltaCreation.CreateDeltaFile(
                    tempFolder,
                    baseFileLocation,
                    newFileLocation,
                    tmpDeltaFile.Location,
                    intendedOs,
                    out var extension,
                    out var deltaFileStream))
            {
                //Wasn't able to create delta file, report back as fail
                _logger.Error("Wasn't able to create delta file");
                return(false);
            }

            //Check that we got something to work with
            if (deltaFileStream == null && !File.Exists(tmpDeltaFile.Location))
            {
                _logger.Error("We have no delta file/stream to work off somehow");
                return(false);
            }

            //Get hash and filesize to add to file
            var newFileStream = File.OpenRead(newFileLocation);
            var newFilesize   = newFileStream.Length;

            /*Check that the delta file will take up less space, if not fail here
             * as it's not worth making it a delta file (Will take more time and processing power then just copying on the user's device)*/
            if ((deltaFileStream?.Length ?? new FileInfo(tmpDeltaFile.Location).Length) >= newFilesize)
            {
                _logger.Warning("{0} will take up more space as a delta file then as a \"new\" file, failing to trigger it being added as a new file", baseFileLocation.GetRelativePath(newFileLocation));
                newFileStream.Dispose();
                deltaFileStream?.Dispose();
                return(false);
            }

            var hash = SHA256Util.CreateSHA256Hash(newFileStream);

            newFileStream.Dispose();

            //Grab file and add it to the set of files
            deltaFileStream ??= tmpDeltaFile.GetStream(FileMode.Open);
            var addSuccessful = AddFile(
                zipArchive,
                deltaFileStream,
                baseFileLocation.GetRelativePath(newFileLocation) + extension + extensionEnd,
                filesize: newFilesize,
                sha256Hash: hash);

            //Dispose stream and report back if we was able to add file
            deltaFileStream.Dispose();
            return(addSuccessful);
        }
Пример #20
0
 public TestLibraryModel(TemporaryFolder testFolder)
     : base(testFolder.Path, new CollectionSettings(), new BookSelection(), new SourceCollectionsList(),
            null, null, new CreateFromSourceBookCommand(), null, null, null)
 {
     TestFolderPath = testFolder.Path;
 }
Пример #21
0
 public TestEnvironment()
 {
     _wesayProjectFolder = new TemporaryFolder("WesayProject");
     _ldmlWsFolder       = new TemporaryFolder(_wesayProjectFolder, "WritingSystems");
     _wsPrefsFile        = new TempFile(_ldmlWsFolder.Path);
 }
Пример #22
0
 public override void SetUp()
 {
     _tempFolder         = new TemporaryFolder();
     _persistedFilePath  = _tempFolder.GetTemporaryFile();
     DataMapperUnderTest = new LiftLexEntryRepository(_persistedFilePath);
 }
        public void SyncLocalAndRepoCollectionFiles_SyncsInRightDirection()
        {
            using (var collectionFolder =
                       new TemporaryFolder("SyncLocalAndRepoCollectionFiles_SyncsInRightDirection_Collection"))
            {
                using (var repoFolder =
                           new TemporaryFolder("SyncLocalAndRepoCollectionFiles_SyncsInRightDirection_Shared"))
                {
                    var settingsFileName =
                        Path.ChangeExtension(Path.GetFileName(collectionFolder.FolderPath), "bloomCollection");
                    var settingsPath = Path.Combine(collectionFolder.FolderPath, settingsFileName);
                    var tcManager    = new TeamCollectionManager(settingsPath, null, new BookRenamedEvent(),
                                                                 new BookStatusChangeEvent(), null, null);
                    var tc = new FolderTeamCollection(tcManager, collectionFolder.FolderPath, repoFolder.FolderPath);
                    tc.CollectionId = Bloom.TeamCollection.TeamCollection.GenerateCollectionId();
                    var bloomCollectionPath =
                        Bloom.TeamCollection.TeamCollection.CollectionPath(collectionFolder.FolderPath);
                    Assert.That(tc.LocalCollectionFilesRecordedSyncTime, Is.EqualTo(DateTime.MinValue));
                    File.WriteAllText(bloomCollectionPath, "This is a fake collection file");
                    var collectionStylesPath = Path.Combine(collectionFolder.FolderPath, "customCollectionStyles.css");
                    RobustFile.WriteAllText(collectionStylesPath, "This is the collection styles");

                    // SUT 1: nothing in repo, no sync time file. Copies to repo.
                    tc.SyncLocalAndRepoCollectionFiles();

                    var localWriteTime1 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime1, Is.LessThanOrEqualTo(DateTime.Now));
                    Assert.That(localWriteTime1, Is.GreaterThan(DateTime.Now.Subtract(new TimeSpan(0, 0, 5, 0))));
                    var otherFilesPath = FolderTeamCollection.GetRepoProjectFilesZipPath(repoFolder.FolderPath);
                    Assert.That(File.Exists(otherFilesPath));
                    var anotherPlace = Path.Combine(repoFolder.FolderPath, "anotherPlace.zip");
                    RobustFile.Copy(otherFilesPath, anotherPlace);
                    var repoWriteTime1       = new FileInfo(otherFilesPath).LastWriteTime;
                    var collectionWriteTime1 = new FileInfo(bloomCollectionPath).LastWriteTime;

                    // SUT 2: nothing has changed. But it's a startup, so sync still happens to local.
                    tc.SyncLocalAndRepoCollectionFiles();
                    var localWriteTime2 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime2, Is.GreaterThanOrEqualTo(localWriteTime1));
                    Assert.That(new FileInfo(otherFilesPath).LastWriteTime, Is.EqualTo(repoWriteTime1));
                    Assert.That(new FileInfo(bloomCollectionPath).LastWriteTime,
                                Is.GreaterThanOrEqualTo(collectionWriteTime1));

                    File.WriteAllText(bloomCollectionPath, "This is a modified fake collection file");
                    var collectionWriteTime2 = new FileInfo(bloomCollectionPath).LastWriteTime;

                    // SUT 3: local change copied to repo (only when not at startup)
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    var localWriteTime3 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime3, Is.GreaterThan(localWriteTime1),
                                "localWriteTime3 should be greater than localWriteTime1");
                    var repoWriteTime2 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime2, Is.GreaterThan(repoWriteTime1),
                                "repoWriteTime2 should be greater than repoWriteTime1");
                    // not modified by sync
                    Assert.That(new FileInfo(bloomCollectionPath).LastWriteTime, Is.EqualTo(collectionWriteTime2));

                    File.WriteAllText(bloomCollectionPath, "This is a further modified fake collection file");
                    var collectionWriteTime3 = new FileInfo(bloomCollectionPath).LastWriteTime;
                    var version2Path         = Path.Combine(repoFolder.FolderPath, "version2.zip");
                    RobustFile.Copy(otherFilesPath, version2Path);
                    // modify the remote version by copying the old one back.
                    Thread.Sleep(10);
                    RobustFile.Copy(anotherPlace, otherFilesPath, true);
                    var repoWriteTime3 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime3, Is.GreaterThan(collectionWriteTime3),
                                "repo file written after local collection file [sanity check]");

                    // SUT 4: both changed: repo wins
                    tc.SyncLocalAndRepoCollectionFiles();
                    var localWriteTime4 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime4, Is.GreaterThan(localWriteTime3),
                                "localWriteTime4 should be greater than localWriteTime3");
                    var repoWriteTime4 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime4, Is.EqualTo(repoWriteTime3));                     // not modified by sync
                    Assert.That(new FileInfo(bloomCollectionPath).LastWriteTime, Is.GreaterThan(collectionWriteTime3),
                                "bloomCollection LastWriteTime should be greater than collectionWriteTime3");
                    // We got the original back.
                    Assert.That(File.ReadAllText(bloomCollectionPath), Is.EqualTo("This is a fake collection file"));

                    Thread.Sleep(10);
                    var allowedWords = Path.Combine(collectionFolder.FolderPath, "Allowed Words");
                    Directory.CreateDirectory(allowedWords);
                    File.WriteAllText(Path.Combine(allowedWords, "file1.txt"), "fake word list");

                    // SUT5: local allowed words added
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    var localWriteTime5 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime5, Is.GreaterThan(localWriteTime4),
                                "localWriteTime5 should be greater than localWriteTime4");
                    var repoWriteTime5 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime5, Is.GreaterThan(repoWriteTime4),
                                "repoWriteTime5 should be greater than repoWriteTime4");

                    Thread.Sleep(5);
                    var sampleTexts = Path.Combine(collectionFolder.FolderPath, "Sample Texts");
                    Directory.CreateDirectory(sampleTexts);
                    File.WriteAllText(Path.Combine(allowedWords, "sample1.txt"), "fake sample list");

                    // SUT6: local sample texts added
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    var localWriteTime6 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime6, Is.GreaterThan(localWriteTime5),
                                "localWriteTime6 should be greater than localWriteTime5");
                    var repoWriteTime6 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime6, Is.GreaterThan(repoWriteTime5),
                                "repoWriteTime6 should be greater than repoWriteTime5");

                    Thread.Sleep(10);
                    File.WriteAllText(Path.Combine(allowedWords, "sample1.txt"), "fake sample list");

                    // SUT7: local file write time modified, but not actually changed. Want the sync time to
                    // update, but NOT to write the remote file.
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    var localWriteTime7 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTime7, Is.GreaterThan(localWriteTime6),
                                "localWriteTime7 should be greater than localWriteTime6");
                    var repoWriteTime7 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTime7, Is.EqualTo(repoWriteTime6));

                    tc._haveShownRemoteSettingsChangeWarning = false;
                    File.WriteAllText(bloomCollectionPath, "This is a modified fake collection file, for SUT 8");
                    var collectionWriteTimeBeforeSut8 = new FileInfo(bloomCollectionPath).LastWriteTime;
                    var localWriteTimeBeforeSut8      = tc.LocalCollectionFilesRecordedSyncTime();
                    var repoWriteTimeBeforeSut8       = new FileInfo(otherFilesPath).LastWriteTime;

                    // SUT 8: local change copied to repo on idle
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    Assert.That(tc._haveShownRemoteSettingsChangeWarning, Is.False, "user should not have been warned");
                    var localWriteTimeAfterSut8 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTimeAfterSut8, Is.GreaterThan(localWriteTimeBeforeSut8),
                                "localWriteTime should increase copying on idle");
                    var repoWriteTimeAfterSut8 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTimeAfterSut8, Is.GreaterThan(repoWriteTimeBeforeSut8),
                                "repoWriteTime should increase copying on idle");
                    // not modified by sync
                    Assert.That(new FileInfo(bloomCollectionPath).LastWriteTime,
                                Is.EqualTo(collectionWriteTimeBeforeSut8));

                    // modify the remote version by copying version2 back.
                    Thread.Sleep(10);
                    var repoWriteTimeBeforeSut9Copy = new FileInfo(otherFilesPath).LastWriteTime;
                    RobustFile.Copy(version2Path, otherFilesPath, true);
                    var collectionWriteTimeBeforeSut9 = new FileInfo(bloomCollectionPath).LastWriteTime;
                    var repoWriteTimeBeforeSut9       = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTimeBeforeSut9, Is.GreaterThan(repoWriteTimeBeforeSut9Copy),
                                "repo file written after local collection file [sanity check]");
                    tc._haveShownRemoteSettingsChangeWarning = false;

                    // SUT9: repo modified, doing check on idle. No changes or warning.
                    tc.SyncLocalAndRepoCollectionFiles(false);
                    Assert.That(tc._haveShownRemoteSettingsChangeWarning, Is.False, "user should not have been warned");
                    var collectionWriteTimeAfterSut9 = new FileInfo(bloomCollectionPath).LastWriteTime;
                    Assert.That(collectionWriteTimeAfterSut9, Is.EqualTo(collectionWriteTimeBeforeSut9),
                                "local settings should not have been modified");

                    File.WriteAllText(bloomCollectionPath, "This is a modified fake collection file, for SUT 10");
                    var collectionWriteTimeBeforeSut10 = new FileInfo(bloomCollectionPath).LastWriteTime;
                    var localWriteTimeBeforeSut10      = tc.LocalCollectionFilesRecordedSyncTime();
                    var repoWriteTimeBeforeSut10       = new FileInfo(otherFilesPath).LastWriteTime;

                    // SUT10: both modified, doing check on idle. No changes. User warned.
                    using (var nfes = new ErrorReport.NonFatalErrorReportExpected())
                    {
                        tc.SyncLocalAndRepoCollectionFiles(false);
                    }

                    Assert.That(tc._haveShownRemoteSettingsChangeWarning, Is.True, "user should have been warned");
                    var localWriteTimeAfterSut10 = tc.LocalCollectionFilesRecordedSyncTime();
                    Assert.That(localWriteTimeAfterSut10, Is.EqualTo(localWriteTimeBeforeSut10),
                                "localWriteTime should not be changed by idle sync where both changed");
                    var repoWriteTimeAfterSut10 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTimeAfterSut10, Is.EqualTo(repoWriteTimeBeforeSut10),
                                "repo should not be modified by idle sync where both changed");                 // not modified by sync
                    Assert.That(new FileInfo(bloomCollectionPath).LastWriteTime,
                                Is.EqualTo(collectionWriteTimeBeforeSut10),
                                "bloomCollection LastWriteTime should not be changed by idle sync both changed");

                    // Get everything back in sync
                    tc.SyncLocalAndRepoCollectionFiles();
                    var localWriteTimeBeforeSut11 = tc.LocalCollectionFilesRecordedSyncTime();
                    var repoWriteTimeBeforeSut11  = new FileInfo(otherFilesPath).LastWriteTime;
                    RobustFile.WriteAllText(collectionStylesPath, "This is the modified collection styles");

                    // SUT11: custom collection styles modified while Bloom was not running. Copied to repo.
                    tc.SyncLocalAndRepoCollectionFiles();
                    var repoWriteTimeAfterSut11 = new FileInfo(otherFilesPath).LastWriteTime;
                    Assert.That(repoWriteTimeAfterSut11, Is.GreaterThanOrEqualTo(repoWriteTimeBeforeSut11));
                    var localWriteTimeAfterSut11 = tc.LocalCollectionFilesRecordedSyncTime();
                    // We will update the sync time even though the write is the other way.
                    Assert.That(localWriteTimeAfterSut11, Is.GreaterThan(localWriteTimeBeforeSut11));
                    Assert.That(File.ReadAllText(collectionStylesPath),
                                Is.EqualTo("This is the modified collection styles"));
                }
            }
        }
Пример #24
0
        public void FileNoCollision()
        {
            using( TemporaryFolder folder = new TemporaryFolder() )
            {
                var file = folder.CreateFile();

                var originalName = file.Name;
                const string newName = "test";

                var rule = new RenameRule
                {
                    Name = newName
                };

                rule.Apply(file.FileInfo, environment);

                Assert.IsFalse(folder.Files.Any(x => x.Name == originalName));
                Assert.IsTrue(folder.Files.Any(x => x.Name == newName));
                Assert.AreEqual(1, folder.Files.Count());
            }
        }
Пример #25
0
 public BundleStorageEnvForTest()
 {
     BaseFolder = new TemporaryFolder("BundleStorageHelperTests");
 }
Пример #26
0
 public ExternalResourceAnonymousInnerClass(ServletContainerRuleFactory outerInstance, TemporaryFolder tempFolder)
 {
     this.outerInstance = outerInstance;
     this.tempFolder    = tempFolder;
     bootstrap          = new CXFTomcatServerBootstrap(outerInstance.webXmlResource);
 }
Пример #27
0
 public PullStorageEnvForTest()
 {
     BaseFolder = new TemporaryFolder("PullStorageHelperTests");
 }
Пример #28
0
        public void UpdateToBranchHeadCallsReturnExpected_UpdateResults()
        {
            using (var testRoot = new TemporaryFolder("RepositoryTests"))
            {
                var progress = new NullProgress();
                HgRepository.CreateRepositoryInExistingDir(testRoot.Path, progress);
                // fileX and fileXRev are zero based indexing, since those local commit numbers in Hg are zero based indexing.
                using (var file0 = testRoot.GetNewTempFile(true))
                {
                    var repo = new HgRepository(testRoot.Path, new NullProgress());

                    // SUT
                    Assert.That(repo.UpdateToBranchHead("fakebranchname"), Is.EqualTo(HgRepository.UpdateResults.NoCommitsInRepository));

                    repo.AddAndCheckinFile(file0.Path);
                    var file0Rev = repo.GetRevisionWorkingSetIsBasedOn();

                    // SUT
                    Assert.That(repo.UpdateToBranchHead(file0Rev.Branch), Is.EqualTo(HgRepository.UpdateResults.AlreadyOnIt));

                    // SUT
                    Assert.That(repo.UpdateToBranchHead("NoSuchBranch"), Is.EqualTo(HgRepository.UpdateResults.NoSuchBranch));

                    using (var file1 = testRoot.GetNewTempFile(true))
                    {
                        // Make new branch.
                        repo.BranchingHelper.Branch(progress, "newbranch");
                        repo.AddAndCheckinFile(file1.Path);
                        var file1Rev = repo.GetRevisionWorkingSetIsBasedOn();
                        Assert.That(repo.UpdateToBranchHead(file1Rev.Branch), Is.EqualTo(HgRepository.UpdateResults.AlreadyOnIt));

                        // Go back to commit 0 and create another "newbranch", which should then be a two headed monster.
                        repo.Update("0");
                        repo.BranchingHelper.Branch(progress, "newbranch");
                        File.WriteAllText(file1.Path, @"new contents");
                        repo.Commit(true, "Force double headed branch");
                        var heads = repo.GetHeads().ToList();
                        Assert.That(heads.Count, Is.EqualTo(3));

                        // SUT
                        Assert.That(repo.UpdateToBranchHead(file1Rev.Branch), Is.EqualTo(HgRepository.UpdateResults.AlreadyOnIt));
                        var testRev = repo.GetRevisionWorkingSetIsBasedOn();
                        Assert.That(testRev.Branch, Is.EqualTo("newbranch"));
                        Assert.That(testRev.Number.LocalRevisionNumber, Is.EqualTo("2"));

                        // Switch to older head of 'newbranch'
                        // (Goes from rev 2 back to rev 1, both of which are on the same branch (newbranch).)
                        repo.Update("1");

                        // SUT
                        // Returns "Success", because we moved from rev 1 to rev 2 (higher rev number) in the same branch, which branch has two heads.)
                        Assert.That(repo.UpdateToBranchHead(file1Rev.Branch), Is.EqualTo(HgRepository.UpdateResults.Success));
                        testRev = repo.GetRevisionWorkingSetIsBasedOn();
                        Assert.That(testRev.Branch, Is.EqualTo("newbranch"));
                        Assert.That(testRev.Number.LocalRevisionNumber, Is.EqualTo("2"));

                        // Switch to commit 0.
                        repo.Update("0");
                        testRev = repo.GetRevisionWorkingSetIsBasedOn();
                        Assert.That(testRev.Branch, Is.EqualTo(string.Empty));
                        Assert.That(testRev.Number.LocalRevisionNumber, Is.EqualTo("0"));

                        // SUT
                        Assert.That(repo.UpdateToBranchHead(file1Rev.Branch), Is.EqualTo(HgRepository.UpdateResults.Success));
                        testRev = repo.GetRevisionWorkingSetIsBasedOn();
                        Assert.That(testRev.Branch, Is.EqualTo("newbranch"));
                        Assert.That(testRev.Number.LocalRevisionNumber, Is.EqualTo("2"));
                    }
                }
            }
        }
Пример #29
0
 public void Setup()
 {
     ErrorReport.IsOkToInteractWithUser = false;
     _parentFolder = new TemporaryFolder("ProjectElementTest");
 }
Пример #30
0
 public void TearDown()
 {
     _parentFolder.Dispose();
     _parentFolder = null;
 }
Пример #31
0
        /// <summary>
        /// Creates the .bloompub and bloomdigital folders
        /// </summary>
        private static CreateArtifactsExitCode CreateBloomDigitalArtifacts(string bookPath, string creator, string zippedBloomPubOutputPath, string unzippedBloomDigitalOutputPath)
        {
#if DEBUG
            // Useful for allowing debugging of Bloom while running the harvester
            //MessageBox.Show("Attach debugger now");
#endif
            var exitCode = CreateArtifactsExitCode.Success;

            using (var tempBloomPub = TempFile.CreateAndGetPathButDontMakeTheFile())
            {
                if (String.IsNullOrEmpty(zippedBloomPubOutputPath))
                {
                    zippedBloomPubOutputPath = tempBloomPub.Path;
                }

                BookServer bookServer = _projectContext.BookServer;

                var  metadata       = BookMetaData.FromFolder(bookPath);
                bool isTemplateBook = metadata.IsSuitableForMakingShells;

                // Build artifacts the same way from the harvester as on the user's local machine.
                // (similarly to a bulk publish operation)
                // See https://issues.bloomlibrary.org/youtrack/issue/BL-10300.
                var bookInfo = new BookInfo(bookPath, false);
                var settings = AndroidPublishSettings.GetPublishSettingsForBook(bookServer, bookInfo);

                using (var folderForUnzipped = new TemporaryFolder("BloomCreateArtifacts_Unzipped"))
                {
                    // Ensure directory exists, just in case.
                    Directory.CreateDirectory(Path.GetDirectoryName(zippedBloomPubOutputPath));
                    // Make the bloompub
                    string unzippedPath = BloomPubMaker.CreateBloomPub(
                        zippedBloomPubOutputPath,
                        bookPath,
                        bookServer,
                        new Bloom.web.NullWebSocketProgress(),
                        folderForUnzipped,
                        creator,
                        isTemplateBook,
                        settings);

                    // Currently the zipping process does some things we actually need, like making the cover picture
                    // transparent (BL-7437). Eventually we plan to separate the preparation and zipping steps (BL-7445).
                    // Until that is done, the most reliable way to get an unzipped BloomPUB for our preview is to actually
                    // unzip the BloomPUB.
                    if (!String.IsNullOrEmpty(unzippedBloomDigitalOutputPath))
                    {
                        SIL.IO.RobustIO.DeleteDirectory(unzippedBloomDigitalOutputPath, recursive: true);                           // In case the folder isn't already empty

                        // Ensure directory exists, just in case.
                        Directory.CreateDirectory(Path.GetDirectoryName(unzippedBloomDigitalOutputPath));

                        ZipFile.ExtractToDirectory(zippedBloomPubOutputPath, unzippedBloomDigitalOutputPath);

                        exitCode |= RenameBloomDigitalFiles(unzippedBloomDigitalOutputPath);
                    }
                }
            }

            return(exitCode);
        }
Пример #32
0
 private Project CreateProject(TemporaryFolder parent)
 {
     return(new Project(parent.Combine("foo", "foo." + Project.ProjectSettingsFileExtension), null, null));
 }
Пример #33
0
        public void OneTimeSetup()
        {
            _repoFolder       = new TemporaryFolder("SyncAtStartup_Repo");
            _collectionFolder = new TemporaryFolder("SyncAtStartup_Local");
            FolderTeamCollection.CreateTeamCollectionLinkFile(_collectionFolder.FolderPath,
                                                              _repoFolder.FolderPath);
            _mockTcManager           = new Mock <ITeamCollectionManager>();
            _tcLog                   = new TeamCollectionMessageLog(TeamCollectionManager.GetTcLogPathFromLcPath(_collectionFolder.FolderPath));
            _collection              = new FolderTeamCollection(_mockTcManager.Object, _collectionFolder.FolderPath, _repoFolder.FolderPath, tcLog: _tcLog);
            _collection.CollectionId = Bloom.TeamCollection.TeamCollection.GenerateCollectionId();
            TeamCollectionManager.ForceCurrentUserForTests("*****@*****.**");

            // Simulate a book that was once shared, but has been deleted from the repo folder (has a tombstone).
            MakeBook("Should be deleted", "This should be deleted as it has local status but is not shared", true);
            var bookFolderPath = Path.Combine(_collectionFolder.FolderPath, "Should be deleted");

            _collection.DeleteBookFromRepo(bookFolderPath);

            // Simulate a book that was once shared, but has been deleted from the repo folder. But there is no tombstone.
            // (Despite the name, it is only converted to a new local in the default case. When we do a First Time Join,
            // it just gets copied into the repo.)
            MakeBook("Should be converted to new local", "This should become a new local (no status) book as it has local status but is not in the repo", true);
            var delPath = Path.Combine(_repoFolder.FolderPath, "Books", "Should be converted to new local.bloom");

            RobustFile.Delete(delPath);

            // Simulate a book newly created locally. Not in repo, but should not be deleted.
            MakeBook("A book", "This should survive as it has no local status", false);
            // By the way, like most new books, it got renamed early in life...twice
            SimulateRename(_collection, "A book", "An early name");
            SimulateRename(_collection, "An early name", "New book");

            // Simulate a book that needs nothing done to it. It's the same locally and on the repo.
            MakeBook("Keep me", "This needs nothing done to it");

            // Simulate a book that is checked out locally to the current user, but the file has
            // been deleted on the repo.
            MakeBook("Keep me too", "This also needs nothing done", false);
            _collection.WriteLocalStatus("Keep me too", new BookStatus().WithLockedBy("*****@*****.**"));

            // Simlulate a book that is only in the team repo
            MakeBook("Add me", "Fetch to local");
            var delPathAddMe = Path.Combine(_collectionFolder.FolderPath, "Add me");

            SIL.IO.RobustIO.DeleteDirectoryAndContents(delPathAddMe);

            // Simulate a book that was checked in, then checked out again and renamed,
            // but not yet checked in. Both "A renamed book" folder and content and "An old name.bloom"
            // should survive. (Except for an obscure reason when joining a TC...see comment in the test.)
            MakeBook("An old name", "Should be kept in both places with different names");
            _collection.AttemptLock("An old name", "*****@*****.**");
            SimulateRename(_collection, "An old name", "an intermediate name");
            SimulateRename(_collection, "an intermediate name", "A renamed book");

            // Simulate a book that is not checked out locally and has been modified elsewhere
            MakeBook("Update me", "Needs to be become this locally");
            UpdateLocalBook("Update me", "This is supposed to be an older value, not edited locally");

            // Simulate a book that is checked out locally but not in the repo, and where the saved local
            // checksum equals the repo checksum, and it is not checked out in the repo. This would
            // typically indicate that someone remote forced a checkout, perhaps while this user was
            // offline, but checked in again without making changes.
            // Also pretend it has been modified locally.
            // Test result: collection is updated to indicate the local checkout. Local changes are not lost.
            MakeBook("Check me out", "Local and remote checksums correspond to this");
            UpdateLocalBook("Check me out", "This is supposed to be a newer value from local editing", false);
            var oldLocalStatus = _collection.GetLocalStatus("Check me out");
            var newLocalStatus = oldLocalStatus.WithLockedBy(Bloom.TeamCollection.TeamCollectionManager.CurrentUser);

            _checkMeOutOriginalChecksum = oldLocalStatus.checksum;
            _collection.WriteLocalStatus("Check me out", newLocalStatus);

            // Simulate a book that appears newly-created locally (no local status) but is also in the
            // repo. This would indicate two people coincidentally creating a book with the same name.
            // Test result: the local book should get renamed (both folder and htm).
            // When merging while joining a new TC, this case is treated as a conflict and the
            // local book is moved to Lost and Found.
            MakeBook("Rename local", "This content is on the server");
            _collection.AttemptLock("Rename local", "*****@*****.**");
            UpdateLocalBook("Rename local", "This is a new book created independently");
            var statusFilePath = Bloom.TeamCollection.TeamCollection.GetStatusFilePath("Rename local", _collectionFolder.FolderPath);

            RobustFile.Delete(statusFilePath);

            // Simulate a book that is checked out locally but also checked out, to a different user
            // or machine, on the repo. This would indicate some sort of manual intervention, perhaps
            // while this user was long offline. The book has not been modified locally, but the local
            // status is out of date.
            // Test result: local status is updated to reflect the remote checkout, book content updated to repo.
            MakeBook("Update and undo checkout", "This content is everywhere");
            _collection.AttemptLock("Update and undo checkout", "*****@*****.**");
            _collection.WriteLocalStatus("Update and undo checkout", _collection.GetStatus("Update and undo checkout").WithLockedBy(Bloom.TeamCollection.TeamCollectionManager.CurrentUser));

            // Simulate a book that is checked out locally and not on the server, but the repo and (old)
            // local checksums are different. The book has not been edited locally.
            // Test result: book is updated to match repo. Local and remote status should match...review: which wins?
            MakeBook("Update and checkout", "This content is on the server");
            UpdateLocalBook("Update and checkout", "This simulates older content changed remotely but not locally");
            _collection.WriteLocalStatus("Update and checkout", _collection.GetLocalStatus("Update and checkout").WithLockedBy(Bloom.TeamCollection.TeamCollectionManager.CurrentUser));

            // Simulate a book that is checked out and modified locally, but has also been modified
            // remotely.
            // Test result: current local state is saved in lost-and-found. Repo version of book and state
            // copied to local. Warning to user.
            MakeBook("Update content and status and warn", "This simulates new content on server");
            _collection.AttemptLock("Update content and status and warn", "*****@*****.**");
            UpdateLocalBook("Update content and status and warn", "This is supposed to be the newest value from local editing");
            var newStatus = _collection.GetStatus("Update content and status and warn").WithLockedBy(Bloom.TeamCollection.TeamCollectionManager.CurrentUser)
                            .WithChecksum("different from either");

            _collection.WriteLocalStatus("Update content and status and warn", newStatus);

            // Simulate a book that is checked out and modified locally, but is also checked out by another
            // user or machine in the repo. It has not (yet) been modified remotely.
            // Test result: current local state is saved in lost-and-found. Repo version of book and state
            // copied to local. Warning to user.
            MakeBook("Update content and status and warn2", "This simulates new content on server");
            _collection.AttemptLock("Update content and status and warn2", "*****@*****.**");
            UpdateLocalBook("Update content and status and warn2", "This is supposed to be the newest value from local editing", false);
            newStatus = _collection.GetStatus("Update content and status and warn2").WithLockedBy(Bloom.TeamCollection.TeamCollectionManager.CurrentUser);
            _collection.WriteLocalStatus("Update content and status and warn2", newStatus);

            // Simulate a book which has no local status, but for which the computed checksum matches
            // the repo one. This could happen if a user obtained the same book independently,
            // or during initial merging of a local and team collection, where much of the material
            // was previously duplicated.
            // Test result: status is copied to local
            MakeBook("copy status", "Same content in both places");
            _collection.AttemptLock("copy status", "*****@*****.**");
            statusFilePath = Bloom.TeamCollection.TeamCollection.GetStatusFilePath("copy status", _collectionFolder.FolderPath);
            RobustFile.Delete(statusFilePath);

            // Simulate a book that was copied from another TC, using File Explorer.
            // It therefore has a book.status file, but with a different guid.
            // Test result: it should survive, and on a new collection sync get copied into the repo
            var copiedEx = "copied with Explorer";

            MakeBook(copiedEx, "This content is only local", false);
            _collection.WriteLocalStatus(copiedEx, new BookStatus(), collectionId: Bloom.TeamCollection.TeamCollection.GenerateCollectionId());

            // Simulate a book that appeared in DropBox when their software found a conflict.
            // It should NOT be copied locally, but instead moved to Lost and Found, with a report.
            MakeBook(kConflictName, "This content is only on the repo, apart from conflicting copies");
            var conflictFolderPath = Path.Combine(_collectionFolder.FolderPath, kConflictName);

            SIL.IO.RobustIO.DeleteDirectoryAndContents(conflictFolderPath);

            _collection.WriteLocalStatus(copiedEx, new BookStatus(), collectionId: Bloom.TeamCollection.TeamCollection.GenerateCollectionId());

            // Simulate a corrupt zip file, only in the repo
            File.WriteAllText(Path.Combine(_repoFolder.FolderPath, "Books", "new corrupt book.bloom"), "This is not a valid zip!");

            // Simulate a corrupt zip file that corresponds to a local book.
            var badZip = "has a bad zip in repo";

            MakeBook(badZip, "This book seems to be in both places, but the repo is corrupt");
            File.WriteAllText(Path.Combine(_repoFolder.FolderPath, "Books", badZip + ".bloom"), "This is also not a valid zip!");

            // Simulate a book that was renamed remotely. That is, there's a local book Old Name, with local status,
            // and there's no repo book by that name, but there's a repo book New Name (and no such local book).
            // The book's meta.json indicates they are the same book.
            // We'll initially make both, with the new name and new content.
            MakeBook(kNewNameForRemoteRename, "This is the new book content after remote editing and rename");
            var oldFolder = Path.Combine(_collectionFolder.FolderPath, kBookRenamedRemotely);
            var newFolder = Path.Combine(_collectionFolder.FolderPath, kNewNameForRemoteRename);

            RobustIO.MoveDirectory(newFolder, oldFolder);              // made at new path, simulate still at old.
            var oldPath = Path.Combine(_collectionFolder.FolderPath, kBookRenamedRemotely,
                                       kBookRenamedRemotely + ".htm"); // simulate old book name and content

            RobustFile.WriteAllText(oldPath, "This is the simulated original book content");
            RobustFile.Delete(Path.Combine(_collectionFolder.FolderPath, kBookRenamedRemotely,
                                           kNewNameForRemoteRename + ".htm")); // get rid of the 'new' content

            // Make a couple of folders that are legitimately present, but not books.
            var allowedWords = Path.Combine(_collectionFolder.FolderPath, "Allowed Words");

            Directory.CreateDirectory(allowedWords);
            File.WriteAllText(Path.Combine(allowedWords, "some sample.txt"), "This a fake word list");
            var sampleTexts = Path.Combine(_collectionFolder.FolderPath, "Sample Texts");

            Directory.CreateDirectory(sampleTexts);
            File.WriteAllText(Path.Combine(sampleTexts, "a sample.txt"), "This a fake sample text");

            _progressSpy = new ProgressSpy();

            // sut for the whole suite!
            Assert.That(_collection.SyncAtStartup(_progressSpy, FirstTimeJoin()), Is.True);
        }
 public void TearDown()
 {
     _tempFolder.Dispose();
     _tempFolder = null;
 }
Пример #35
0
 public void Setup()
 {
     TheUser = new ChorusUser("joe");
     _folder = new TemporaryFolder("NotesModelTests_" + Path.GetRandomFileName());
 }
Пример #36
0
        public void FileNoCollision()
        {
            using( TemporaryFolder folder1 = new TemporaryFolder(), folder2 = new TemporaryFolder() )
            {
                var file = folder1.CreateFile();

                var rule = new MoveRule
                {
                    Destination = folder2.Path
                };

                rule.Apply(file.FileInfo, environment);

                Assert.IsFalse(folder1.Files.Any(x => x.Name == file.Name));
                Assert.IsTrue(folder2.Files.Any(x=>x.Name==file.Name));
            }
        }
Пример #37
0
 private TempFile CreateNotesFile(TemporaryFolder folder, string contents)
 {
     return(new TempFileFromFolder(folder, "one." + AnnotationRepository.FileExtension, "<notes version='0'>" + contents + "</notes>"));
 }
Пример #38
0
        private void AssertFileExists(MirrorController controller, RawDirectoryGroup source, TemporaryFolder destFolder, string fileName)
        {
            string path = destFolder.Combine(controller.DestinationRootForThisUser, source.Name, fileName);

            Assert.IsTrue(File.Exists(path), path);
        }
Пример #39
0
 public void Setup()
 {
     _parentFolder = new TemporaryFolder("FileUtilsTests");
 }