示例#1
0
        public void StorageExceptionTriggersNoOperation()
        {
            this.SetUpMocks();
            int fileLength = 20;

            byte[] content = new byte[fileLength];

            var localFile = this.CreateLocalFile(fileLength, this.modificationDate.AddMinutes(1));

            using (var uploadedContent = new MemoryStream()) {
                localFile.Setup(
                    f =>
                    f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(() => { return(new MemoryStream(content)); });
                var mappedObject = this.CreateMappedFile(this.modificationDate.AddMinutes(1), fileLength, new byte[20]);
                this.storage.AddMappedFile(mappedObject);
                var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.remoteId, this.objectName, this.parentId, fileLength, new byte[20], this.oldChangeToken);
                remoteFile.Setup(r => r.SetContentStream(It.IsAny <IContentStream>(), true, true)).Throws(new CmisStorageException());
                this.manager.SetupCreateTransmissionOnce(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.Object.FullName);

                this.underTest.Solve(localFile.Object, remoteFile.Object);

                this.storage.Verify(s => s.SaveMappedObject(It.IsAny <IMappedObject>()), Times.Never());
                remoteFile.VerifySetContentStream();
            }
        }
示例#2
0
        private void RunSolverToDeleteLocalCacheBeforeContinue(
            AbstractEnhancedSolver solver,
            ContentChangeType localContent  = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            this.cacheFile.Setup(f => f.Exists).Returns(false);

            Mock <MemoryStream> stream = new Mock <MemoryStream>();

            stream.SetupAllProperties();
            stream.Setup(f => f.CanWrite).Returns(true); // required for System.Security.Cryptography.CryptoStream

            this.localFileLength = 0;
            stream.Setup(f => f.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Callback((byte[] buffer, int offset, int count) => this.localFileLength += count);

            this.cacheFile.Setup(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)).Returns(() => {
                this.cacheFile.Setup(f => f.Exists).Returns(true);
                return(stream.Object);
            });

            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.objectId, this.objectName, this.parentId, this.fileContent.Length, this.fileContent, this.changeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            solver.Solve(this.localFile.Object, remoteObject.Object, localContent, remoteContent);

            Assert.That(this.localFileLength, Is.EqualTo(this.fileContent.Length));
            this.cacheFile.Verify(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()), Times.Exactly(2));   // first open in SetupToAbortThePreviousDownload, second open to download
            this.localFile.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
            this.storage.VerifySavedMappedObject(MappedObjectType.File, this.objectId, this.objectName, this.parentId, this.changeToken, true, this.creationDate, this.creationDate, this.fileHash, this.fileContent.Length);
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(this.objectId), Times.Exactly(2));
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(this.objectId), Times.Once());
        }
        public void FileDeletedEventWithoutObjectId()
        {
            var session = new Mock <ISession>();

            session.SetupSessionDefaultValues();
            IDocument remote = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, Id, "name", (string)null).Object;

            session.Setup(s => s.GetObject(Id, It.IsAny <IOperationContext>())).Returns(remote);

            var storage = new Mock <IMetaDataStorage>();

            storage.AddLocalFile(Path, Id, Uuid);

            var fileInfoMock = new Mock <IFileInfo>();

            fileInfoMock.Setup(f => f.FullName).Returns(Path);
            var fileEvent = new FileEvent(fileInfoMock.Object)
            {
                Local = MetaDataChangeType.DELETED
            };
            var fetcher = new RemoteObjectFetcher(session.Object, storage.Object);

            Assert.That(fetcher.Handle(fileEvent), Is.False);
            Assert.That(fileEvent.RemoteFile, Is.Not.Null);
        }
示例#4
0
        public void OneLocalFileCopied()
        {
            var uuid    = Guid.NewGuid();
            var oldFile = this.fsFactory.AddFile(Path.Combine(this.localRootPath, "old"), uuid);

            oldFile.Setup(f => f.LastWriteTimeUtc).Returns(this.lastLocalWriteTime);
            var newFile = this.fsFactory.AddFile(Path.Combine(this.localRootPath, "new"), uuid);

            var remoteSubFolder = MockOfIDocumentUtil.CreateRemoteDocumentMock("streamId", "oldId", oldFile.Object.Name, this.remoteFolder.Object, changeToken: "oldChange");
            var storedFolder    = new MappedObject(oldFile.Object.Name, "oldId", MappedObjectType.File, this.remoteRootId, "oldChange")
            {
                Guid = uuid,
                LastLocalWriteTimeUtc = this.lastLocalWriteTime
            };

            this.storage.SaveMappedObject(storedFolder);
            this.remoteFolder.SetupDescendants(remoteSubFolder.Object);
            this.localFolder.SetupFiles(newFile.Object, oldFile.Object);

            var crawler = this.CreateCrawler();

            Assert.That(crawler.Handle(new StartNextSyncEvent()), Is.True);
            this.queue.Verify(
                q =>
                q.AddEvent(
                    It.Is <FileEvent>(
                        e =>
                        e.LocalFile.Equals(newFile.Object) &&
                        e.Local.Equals(MetaDataChangeType.CREATED))),
                Times.Once());
            this.VerifyThatCountOfAddedEventsIsLimitedTo(Times.Once());
        }
示例#5
0
        public void RunFSEventFileDeleted()
        {
            var storage = this.GetInitializedStorage();
            var path    = new Mock <IFileInfo>();
            var name    = "a";

            path.Setup(p => p.FullName).Returns(Path.Combine(this.localRoot, name));
            string id = "id";

            var mappedObject = new MappedObject(name, id, MappedObjectType.File, null, null);

            storage.SaveMappedObject(mappedObject);

            var session = new Mock <ISession>();

            session.SetupTypeSystem();
            session.SetupSessionDefaultValues();
            session.SetupChangeLogToken("default");
            IDocument remote = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, name, (string)null).Object;

            session.Setup(s => s.GetObject(id, It.IsAny <IOperationContext>())).Returns(remote);
            var myEvent = new FSEvent(WatcherChangeTypes.Deleted, path.Object.FullName, false);
            var queue   = this.CreateQueue(session, storage);

            queue.AddEvent(myEvent);
            queue.Run();

            session.Verify(f => f.Delete(It.Is <IObjectId>(i => i.Id == id), true), Times.Once());
            Assert.That(storage.GetObjectByRemoteId(id), Is.Null);
        }
示例#6
0
        public void RemoteFileAddedAndExtendedAttributesAreAvailable()
        {
            var fileInfo      = new Mock <IFileInfo>();
            var cacheFileInfo = this.fsFactory.SetupDownloadCacheFile();
            var parentDir     = Mock.Of <IDirectoryInfo>(d => d.FullName == Path.GetTempPath());

            fileInfo.SetupAllProperties();
            fileInfo.Setup(f => f.FullName).Returns(this.path);
            fileInfo.Setup(f => f.Name).Returns(this.objectName);
            fileInfo.Setup(f => f.Directory).Returns(parentDir);
            byte[] content      = Encoding.UTF8.GetBytes("content");
            byte[] expectedHash = SHA1Managed.Create().ComputeHash(content);
            cacheFileInfo.SetupAllProperties();
            cacheFileInfo.Setup(f => f.FullName).Returns(this.path + ".sync");
            cacheFileInfo.Setup(f => f.Name).Returns(this.objectName + ".sync");
            cacheFileInfo.Setup(f => f.Directory).Returns(parentDir);
            cacheFileInfo.Setup(f => f.IsExtendedAttributeAvailable()).Returns(true);
            using (var stream = new MemoryStream()) {
                cacheFileInfo.Setup(f => f.Open(FileMode.Create, FileAccess.Write, FileShare.Read)).Returns(stream);
                this.fsFactory.AddIFileInfo(cacheFileInfo.Object);

                Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.id, this.objectName, this.parentId, content.Length, content, this.lastChangeToken);
                remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

                this.underTest.Solve(fileInfo.Object, remoteObject.Object);

                cacheFileInfo.Verify(f => f.Open(FileMode.Create, FileAccess.Write, FileShare.Read), Times.Once());
                cacheFileInfo.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Once());
                cacheFileInfo.Verify(f => f.MoveTo(this.path), Times.Once());
                fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
                this.storage.VerifySavedMappedObject(MappedObjectType.File, this.id, this.objectName, this.parentId, this.lastChangeToken, true, this.creationDate, this.creationDate, expectedHash, content.Length);
            }
        }
示例#7
0
        public void LocalFileModificationDateNotWritableShallNotThrow()
        {
            this.SetUpMocks();
            var newModificationDate = this.modificationDate.AddHours(1);
            int fileLength          = 20;

            byte[] content   = new byte[fileLength];
            var    localFile = this.CreateLocalFile(fileLength, this.modificationDate.AddMinutes(1));

            using (var uploadedContent = new MemoryStream()) {
                localFile.Setup(
                    f =>
                    f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(() => { return(new MemoryStream(content)); });
                var mappedObject = this.CreateMappedObject(true, this.modificationDate.AddMinutes(1), fileLength, new byte[20]);
                this.storage.AddMappedFile(mappedObject);
                var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.remoteId, this.objectName, this.parentId, fileLength, new byte[fileLength], this.oldChangeToken);
                remoteFile.Setup(r => r.SetContentStream(It.IsAny <IContentStream>(), true, true)).Callback <IContentStream, bool, bool>(
                    (s, o, r) =>
                    { s.Stream.CopyTo(uploadedContent);
                      remoteFile.Setup(f => f.LastModificationDate).Returns(newModificationDate);
                      remoteFile.Setup(f => f.ChangeToken).Returns(this.newChangeToken); });
                this.manager.SetupCreateTransmissionOnce(TransmissionType.UPLOAD_MODIFIED_FILE, localFile.Object.FullName);

                this.underTest.Solve(localFile.Object, remoteFile.Object);
            }

            localFile.VerifyThatLocalFileObjectLastWriteTimeUtcIsNeverModified();
            this.manager.VerifyThatTransmissionWasCreatedOnce();
        }
示例#8
0
        public void MoveFileToNewLocation()
        {
            DateTime modifiedDate    = DateTime.UtcNow.AddMinutes(1);
            string   oldFileName     = "a";
            string   subFolderName   = "sub";
            string   subFolderId     = "sub";
            string   newFileName     = "b";
            string   oldPath         = Path.Combine(Path.GetTempPath(), oldFileName);
            string   oldRemotePath   = "/" + oldFileName;
            string   newPath         = Path.Combine(Path.GetTempPath(), subFolderName, newFileName);
            string   id              = "id";
            string   parentId        = "papa";
            string   lastChangeToken = "token";

            var fileInfo = new Mock <IFileInfo>();

            fileInfo.Setup(d => d.FullName).Returns(oldPath);
            fileInfo.Setup(d => d.Name).Returns(oldFileName);
            fileInfo.Setup(d => d.Directory).Returns(Mock.Of <IDirectoryInfo>(p => p.FullName == Path.GetTempPath()));

            var fileParents = new List <IFolder>();

            fileParents.Add(Mock.Of <IFolder>(f => f.Id == subFolderId));
            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, newFileName, (string)null, changeToken: lastChangeToken);

            remoteObject.Setup(f => f.Parents).Returns(fileParents);
            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)modifiedDate);

            var mappedFile = Mock.Of <IMappedObject>(
                f =>
                f.Name == oldFileName &&
                f.RemoteObjectId == id &&
                f.LastChangeToken == "oldToken" &&
                f.LastRemoteWriteTimeUtc == DateTime.UtcNow &&
                f.Type == MappedObjectType.File &&
                f.ParentId == parentId);
            var mappedSubFolder = Mock.Of <IMappedObject>(
                f =>
                f.Name == subFolderName &&
                f.RemoteObjectId == subFolderId &&
                f.LastChangeToken == "oldToken" &&
                f.Type == MappedObjectType.Folder &&
                f.ParentId == parentId);

            this.storage.AddMappedFolder(mappedFile, oldPath, oldRemotePath);
            this.storage.AddMappedFolder(mappedSubFolder, Path.Combine(Path.GetTempPath(), subFolderName), "/" + subFolderName);
            this.matcher.Setup(m => m.CreateLocalPath(It.Is <IDocument>(f => f == remoteObject.Object))).Returns(newPath);

            this.underTest.Solve(fileInfo.Object, remoteObject.Object);

            fileInfo.Verify(d => d.MoveTo(It.Is <string>(p => p.Equals(newPath))), Times.Once());

            this.storage.Verify(
                s => s.SaveMappedObject(
                    It.Is <IMappedObject>(f => this.VerifySavedFolder(f, MappedObjectType.File, id, newFileName, subFolderId, lastChangeToken, modifiedDate))),
                Times.Once());
        }
        public void AbortThePreviousDownloadAndContinueTheNextDownload()
        {
            var fileInfo      = new Mock <IFileInfo>();
            var cacheFileInfo = this.fsFactory.SetupDownloadCacheFile();

            byte[] content = new byte[1024 * 1024];
            long   length  = 0;

            this.SetupToAbortThePreviousDownload(fileInfo, cacheFileInfo, content, out length);

            Mock <MemoryStream> stream = new Mock <MemoryStream>();

            stream.SetupAllProperties();
            stream.Setup(f => f.CanWrite).Returns(true);    // required for System.Security.Cryptography.CryptoStream
            stream.Setup(f => f.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Callback((byte[] buffer, int offset, int count) => length += count);
            stream.Setup(f => f.Length).Returns(() => { return(length); });

            long lengthRead = 0;

            stream.Setup(f => f.Seek(It.IsAny <long>(), It.IsAny <SeekOrigin>())).Callback((long offset, SeekOrigin loc) => lengthRead = offset);
            stream.Setup(f => f.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Returns((byte[] buffer, int offset, int count) => {
                if (lengthRead >= length)
                {
                    return(0);
                }

                int countRead = count;
                if (countRead > (length - lengthRead))
                {
                    countRead = (int)(length - lengthRead);
                }

                Array.Copy(content, lengthRead, buffer, offset, countRead);
                lengthRead            += countRead;
                stream.Object.Position = lengthRead;
                return(countRead);
            });

            cacheFileInfo.Setup(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>())).Returns(stream.Object);

            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.id, this.objectName, this.parentId, content.Length, content, this.lastChangeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            this.underTest.Solve(fileInfo.Object, remoteObject.Object);

            Assert.That(length, Is.EqualTo(content.Length));
            stream.Verify(f => f.Seek(0, SeekOrigin.Begin), Times.Once());
            cacheFileInfo.Verify(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()), Times.Exactly(3));   // first open in SetupToAbortThePreviousDownload, second open to validate checksum, third open to download
            cacheFileInfo.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Once());
            cacheFileInfo.Verify(f => f.MoveTo(this.path), Times.Once());
            fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
            this.storage.VerifySavedMappedObject(MappedObjectType.File, this.id, this.objectName, this.parentId, this.lastChangeToken, true, this.creationDate, this.creationDate, SHA1Managed.Create().ComputeHash(content), content.Length);
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(this.id), Times.Exactly(2));
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(this.id), Times.Once());
        }
示例#10
0
        public void OneRemoteFileAdded()
        {
            IDocument newRemoteDocument = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, "id", "name", this.remoteRootId).Object;

            this.remoteFolder.SetupDescendants(newRemoteDocument);
            var crawler = this.CreateCrawler();

            Assert.That(crawler.Handle(new StartNextSyncEvent()), Is.True);
            this.queue.Verify(q => q.AddEvent(It.Is <FileEvent>(e => e.RemoteFile.Equals(newRemoteDocument))), Times.Once());
            this.VerifyThatCountOfAddedEventsIsLimitedTo(Times.Once());
            this.VerifyThatListenerHasBeenUsed();
        }
示例#11
0
        private void RunSolverToContinueDownload(
            AbstractEnhancedSolver solver,
            ContentChangeType localContent  = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            Mock <MemoryStream> stream = new Mock <MemoryStream>();

            stream.SetupAllProperties();
            stream.Setup(f => f.CanWrite).Returns(true); // required for System.Security.Cryptography.CryptoStream
            stream.Setup(f => f.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Callback((byte[] buffer, int offset, int count) => this.localFileLength += count);
            stream.Setup(f => f.Length).Returns(() => { return(this.localFileLength); });

            long lengthRead = 0;

            stream.Setup(f => f.Seek(It.IsAny <long>(), It.IsAny <SeekOrigin>())).Callback((long offset, SeekOrigin loc) => lengthRead = offset);
            stream.Setup(f => f.Read(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Returns((byte[] buffer, int offset, int count) => {
                if (lengthRead >= this.localFileLength)
                {
                    return(0);
                }

                int countRead = count;
                if (countRead > (this.localFileLength - lengthRead))
                {
                    countRead = (int)(this.localFileLength - lengthRead);
                }

                Array.Copy(this.fileContent, lengthRead, buffer, offset, countRead);
                lengthRead            += countRead;
                stream.Object.Position = lengthRead;
                return(countRead);
            });

            this.cacheFile.Setup(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>())).Returns(stream.Object);
            this.cacheFile.Setup(f => f.Length).Returns(() => { return(this.localFileLength); });

            var remoteDocument = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.objectId, this.objectName, this.parentId, this.fileContent.Length, this.fileContent, this.changeToken);

            remoteDocument.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            solver.Solve(this.localFile.Object, remoteDocument.Object, localContent, remoteContent);

            Assert.That(this.localFileLength, Is.EqualTo(this.fileContent.Length));
            stream.Verify(f => f.Seek(0, SeekOrigin.Begin), Times.Once());
            this.cacheFile.Verify(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()), Times.Exactly(3)); // first open in SetupToAbortThePreviousDownload, second open to validate checksum, third open to download
            this.localFile.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
            this.storage.VerifySavedMappedObject(MappedObjectType.File, this.objectId, this.objectName, this.parentId, this.changeToken, true, this.creationDate, this.creationDate, this.fileHash, this.fileContent.Length);
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(this.objectId), Times.Exactly(2));
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(this.objectId), Times.Once());
        }
示例#12
0
        public void LocalFileModificationDateNotWritableShallNotThrow()
        {
            var modificationDate    = DateTime.UtcNow;
            var newModificationDate = modificationDate.AddHours(1);
            var newChangeToken      = "newChangeToken";
            int fileLength          = 20;

            byte[] content = new byte[fileLength];

            var localFile = new Mock <IFileInfo>();

            localFile.SetupProperty(f => f.LastWriteTimeUtc, modificationDate.AddMinutes(1));
            localFile.SetupSet(f => f.LastWriteTimeUtc = It.IsAny <DateTime>()).Throws(new IOException());
            localFile.Setup(f => f.Length).Returns(fileLength);
            localFile.Setup(f => f.FullName).Returns("path");
            localFile.Setup(f => f.Exists).Returns(true);
            using (var uploadedContent = new MemoryStream()) {
                localFile.Setup(
                    f =>
                    f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(() => { return(new MemoryStream(content)); });

                var mappedObject = new MappedObject(
                    "name",
                    "remoteId",
                    MappedObjectType.File,
                    "parentId",
                    "changeToken",
                    fileLength)
                {
                    Guid = Guid.NewGuid(),
                    LastRemoteWriteTimeUtc = modificationDate.AddMinutes(1),
                    LastLocalWriteTimeUtc  = modificationDate,
                    LastChecksum           = new byte[20],
                    ChecksumAlgorithmName  = "SHA-1"
                };
                this.storage.AddMappedFile(mappedObject, "path");
                var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, "remoteId", "name", "parentId", fileLength, new byte[20]);
                remoteFile.Setup(r => r.SetContentStream(It.IsAny <IContentStream>(), true, true)).Callback <IContentStream, bool, bool>(
                    (s, o, r) =>
                    { s.Stream.CopyTo(uploadedContent);
                      remoteFile.Setup(f => f.LastModificationDate).Returns(newModificationDate);
                      remoteFile.Setup(f => f.ChangeToken).Returns(newChangeToken); });

                this.underTest.Solve(localFile.Object, remoteFile.Object);
            }

            localFile.VerifyThatLocalFileObjectLastWriteTimeUtcIsNeverModified();
            this.manager.Verify(m => m.AddTransmission(It.IsAny <FileTransmissionEvent>()), Times.Once());
        }
        public void FilesMovedToEqualFolderAndNamesAndContentAreEqual()
        {
            this.SetupOldMappedFile();
            this.remoteModification = this.localModification - TimeSpan.FromMinutes(30);
            var newLocalParent = this.CreateNewLocalParent(this.newParentUuid);
            var localFile      = this.CreateLocalFile(this.oldName, newLocalParent, this.localModification);
            var remoteFile     = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.remoteObjectId, this.oldName, this.newRemoteParentId, 0, new byte[0], this.newChangeToken);

            remoteFile.SetupUpdateModificationDate(this.remoteModification);

            this.underTest.Solve(localFile.Object, remoteFile.Object, ContentChangeType.NONE, ContentChangeType.NONE);

            remoteFile.VerifyUpdateLastModificationDate(this.localModification);
            this.VerifySavedFile(this.oldName, this.localModification, 0);
        }
        public void FilesMovedToEqualFolderAndBothNamesAreChangedAndLocalModificationIsNewerButContentStaysEqual()
        {
            this.SetupOldMappedFile();
            this.remoteModification = this.localModification - TimeSpan.FromMinutes(30);
            var newLocalParent = this.CreateNewLocalParent(this.newParentUuid, this.newParentPath);
            var localFile      = this.CreateLocalFile(this.newLocalName, newLocalParent, this.localModification);
            var remoteFile     = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.remoteObjectId, this.newRemoteName, this.newRemoteParentId, 0, new byte[0], this.newChangeToken);

            remoteFile.SetupUpdateModificationDate(this.remoteModification);

            this.underTest.Solve(localFile.Object, remoteFile.Object, ContentChangeType.NONE, ContentChangeType.NONE);

            remoteFile.Verify(r => r.Rename(It.IsAny <string>(), It.IsAny <bool>()), Times.Once());
            remoteFile.VerifyUpdateLastModificationDate(this.localModification);
            this.VerifySavedFile(this.newLocalName, this.localModification, 0);
        }
        private ContentChangeEvent PrepareEvent(DotCMIS.Enums.ChangeType type, bool hasContentStream, byte[] contentHash = null)
        {
            var e            = new ContentChangeEvent(type, Id);
            var remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(hasContentStream ? "streamId" : null, Id, "name", (string)null);

            if (contentHash != null)
            {
                remoteObject.SetupContentStreamHash(contentHash);
            }

            var session = new Mock <ISession>();

            session.Setup(s => s.GetObject(It.IsAny <string>(), It.IsAny <IOperationContext>())).Returns(remoteObject.Object);

            e.UpdateObject(session.Object);
            return(e);
        }
示例#16
0
        public void PermissionDeniedTriggersNoOperation()
        {
            Guid uuid             = Guid.NewGuid();
            var  modificationDate = DateTime.UtcNow;
            int  fileLength       = 20;

            byte[] content = new byte[fileLength];

            var localFile = new Mock <IFileInfo>();

            localFile.SetupProperty(f => f.LastWriteTimeUtc, modificationDate.AddMinutes(1));
            localFile.Setup(f => f.Length).Returns(fileLength);
            localFile.Setup(f => f.FullName).Returns("path");
            localFile.SetupGuid(uuid);
            localFile.Setup(f => f.Exists).Returns(true);
            using (var uploadedContent = new MemoryStream()) {
                localFile.Setup(
                    f =>
                    f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(() => { return(new MemoryStream(content)); });

                var mappedObject = new MappedObject(
                    "name",
                    "remoteId",
                    MappedObjectType.File,
                    "parentId",
                    "changeToken",
                    fileLength)
                {
                    Guid = uuid,
                    LastRemoteWriteTimeUtc = modificationDate.AddMinutes(1),
                    LastLocalWriteTimeUtc  = modificationDate,
                    LastChecksum           = new byte[20],
                    ChecksumAlgorithmName  = "SHA-1"
                };
                this.storage.AddMappedFile(mappedObject, "path");
                var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, "remoteId", "name", "parentId", fileLength, new byte[20]);

                remoteFile.Setup(r => r.SetContentStream(It.IsAny <IContentStream>(), true, true)).Throws(new CmisPermissionDeniedException());

                this.underTest.Solve(localFile.Object, remoteFile.Object);

                this.storage.Verify(s => s.SaveMappedObject(It.IsAny <IMappedObject>()), Times.Never());
                remoteFile.VerifySetContentStream();
            }
        }
        public void RenameFile()
        {
            this.SetUpMocks();
            DateTime modifiedDate    = DateTime.UtcNow.AddMinutes(1);
            string   oldFileName     = "a";
            string   newFileName     = "b";
            string   oldPath         = Path.Combine(Path.GetTempPath(), oldFileName);
            string   oldRemotePath   = "/" + oldFileName;
            string   newPath         = Path.Combine(Path.GetTempPath(), newFileName);
            string   id              = "id";
            string   parentId        = "root";
            string   lastChangeToken = "token";
            var      fileInfo        = new Mock <IFileInfo>();

            fileInfo.Setup(f => f.FullName).Returns(oldPath);
            fileInfo.Setup(f => f.Name).Returns(oldFileName);
            fileInfo.SetupProperty(f => f.LastWriteTimeUtc);
            fileInfo.Setup(f => f.Directory).Returns(Mock.Of <IDirectoryInfo>(p => p.FullName == Path.GetTempPath()));

            var remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, newFileName, (string)null, changeToken: lastChangeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)modifiedDate);

            var mappedFile = Mock.Of <IMappedObject>(
                f =>
                f.Name == oldFileName &&
                f.RemoteObjectId == id &&
                f.LastChangeToken == "oldToken" &&
                f.LastRemoteWriteTimeUtc == DateTime.UtcNow &&
                f.Type == MappedObjectType.File &&
                f.ParentId == parentId);

            this.storage.AddMappedFolder(mappedFile, oldPath, oldRemotePath);

            this.underTest.Solve(fileInfo.Object, remoteObject.Object);

            fileInfo.Verify(d => d.MoveTo(It.Is <string>(p => p.Equals(newPath))), Times.Once());

            fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(modifiedDate)), Times.Once());
            this.storage.Verify(
                s => s.SaveMappedObject(
                    It.Is <IMappedObject>(f => this.VerifySavedObject(f, MappedObjectType.File, id, newFileName, parentId, lastChangeToken, modifiedDate))),
                Times.Once());
        }
        public void RemoteFileAddedAndLocalFileIsCreatedWhileDownloadIsInProgress()
        {
            string conflictPath     = this.path + ".conflict";
            var    conflictFileInfo = Mock.Of <IFileInfo>(i => i.FullName == conflictPath);
            var    fileInfo         = new Mock <IFileInfo>();
            var    cacheFileInfo    = this.fsFactory.SetupDownloadCacheFile();
            var    parentDir        = Mock.Of <IDirectoryInfo>(d => d.FullName == Path.GetTempPath());

            fileInfo.SetupAllProperties();
            fileInfo.Setup(f => f.FullName).Returns(this.path);
            fileInfo.Setup(f => f.Name).Returns(this.objectName);
            fileInfo.Setup(f => f.Directory).Returns(parentDir);
            fileInfo.Setup(f => f.Uuid).Returns(Guid.NewGuid());
            byte[] content      = Encoding.UTF8.GetBytes("content");
            byte[] expectedHash = SHA1Managed.Create().ComputeHash(content);
            cacheFileInfo.SetupAllProperties();
            cacheFileInfo.Setup(f => f.FullName).Returns(this.path + ".sync");
            cacheFileInfo.Setup(f => f.Name).Returns(this.objectName + ".sync");
            cacheFileInfo.Setup(f => f.Directory).Returns(parentDir);
            cacheFileInfo.Setup(f => f.IsExtendedAttributeAvailable()).Returns(true);
            cacheFileInfo.Setup(f => f.Replace(fileInfo.Object, conflictFileInfo, true)).Returns(fileInfo.Object);
            using (var stream = new MemoryStream()) {
                cacheFileInfo.Setup(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)).Returns(() => {
                    cacheFileInfo.Setup(f => f.Exists).Returns(true);
                    return(stream);
                });
                cacheFileInfo.Setup(f => f.MoveTo(this.path)).Callback(() => fileInfo.Setup(file => file.Refresh()).Callback(() => fileInfo.Setup(newFile => newFile.Exists).Returns(true))).Throws(new IOException());
                fileInfo.SetupStream(Encoding.UTF8.GetBytes("other content"));
                this.fsFactory.AddIFileInfo(cacheFileInfo.Object);
                this.fsFactory.Setup(f => f.CreateConflictFileInfo(fileInfo.Object)).Returns(conflictFileInfo);
                Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.id, this.objectName, this.parentId, content.Length, content, this.lastChangeToken);
                remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

                this.underTest.Solve(fileInfo.Object, remoteObject.Object);

                cacheFileInfo.Verify(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None), Times.Once());
                cacheFileInfo.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Once());
                cacheFileInfo.Verify(f => f.MoveTo(this.path), Times.Once());
                cacheFileInfo.Verify(f => f.Replace(fileInfo.Object, conflictFileInfo, true), Times.Once());
                fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
                this.storage.VerifySavedMappedObject(MappedObjectType.File, this.id, this.objectName, this.parentId, this.lastChangeToken, true, this.creationDate, this.creationDate, expectedHash, content.Length);
                Mock.Get(conflictFileInfo).VerifySet(c => c.Uuid = null, Times.Once());
            }
        }
示例#19
0
        private void RunSolverToAbortDownload(
            AbstractEnhancedSolver solver,
            ContentChangeType localContent  = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            var stream = new Mock <MemoryStream>();

            stream.SetupAllProperties();
            stream.Setup(f => f.CanWrite).Returns(true); // required for System.Security.Cryptography.CryptoStream

            this.localFileLength = 0;
            stream.Setup(f => f.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Callback((byte[] buffer, int offset, int count) => {
                if (this.localFileLength > 0)
                {
                    foreach (Transmission transmission in this.transmissionManager.ActiveTransmissions)
                    {
                        transmission.Abort();
                    }
                }

                this.localFileLength += count;
            });
            stream.Setup(f => f.Length).Returns(() => { return(this.localFileLength); });

            this.cacheFile.Setup(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)).Returns(() => {
                this.cacheFile.Setup(f => f.Exists).Returns(true);
                return(stream.Object);
            });

            var remoteDocument = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.objectId, this.objectName, this.parentId, this.fileContent.Length, this.fileContent, this.changeToken);

            remoteDocument.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            Assert.Throws <AbortException>(() => solver.Solve(this.localFile.Object, remoteDocument.Object, localContent, remoteContent));

            this.cacheFile.Verify(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None), Times.Once());
            this.cacheFile.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Never());
            this.cacheFile.Verify(f => f.MoveTo(this.localPath), Times.Never());
            this.localFile.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Never());
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(It.IsAny <string>()), Times.Once());
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(It.IsAny <string>()), Times.Never());
            this.storage.Verify(f => f.SaveMappedObject(It.IsAny <IMappedObject>()), Times.Never());
        }
示例#20
0
        public void RemoteDocumentsMetaDataChanged()
        {
            byte[]   hash             = new byte[20];
            DateTime modificationDate = DateTime.UtcNow;
            string   fileName         = "a";
            string   path             = Path.Combine(Path.GetTempPath(), fileName);
            string   id              = "id";
            string   parentId        = "papa";
            string   lastChangeToken = "token";
            string   newChangeToken  = "newToken";

            var fileInfo = new Mock <IFileInfo>();

            fileInfo.Setup(d => d.FullName).Returns(path);
            fileInfo.Setup(d => d.Name).Returns(fileName);
            fileInfo.Setup(d => d.Directory).Returns(Mock.Of <IDirectoryInfo>());

            var mappedObject = new MappedObject(
                fileName,
                id,
                MappedObjectType.File,
                parentId,
                lastChangeToken)
            {
                Guid                  = Guid.NewGuid(),
                LastContentSize       = 0,
                LastChecksum          = hash,
                ChecksumAlgorithmName = "SHA-1"
            };

            this.storage.AddMappedFile(mappedObject);

            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, fileName, parentId, changeToken: newChangeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)modificationDate);

            this.underTest.Solve(fileInfo.Object, remoteObject.Object, ContentChangeType.NONE, ContentChangeType.NONE);

            this.storage.VerifySavedMappedObject(MappedObjectType.File, id, fileName, parentId, newChangeToken, contentSize: 0, checksum: hash);
            fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(modificationDate)), Times.Once());
            this.queue.Verify(q => q.AddEvent(It.IsAny <ISyncEvent>()), Times.Never());
        }
        public void DoNotFetchIfExtendedAttributeIsMissing()
        {
            var session = new Mock <ISession>();

            session.SetupSessionDefaultValues();
            IDocument remote = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, Id, "name", (string)null).Object;

            session.Setup(s => s.GetObject(Id, It.IsAny <IOperationContext>())).Returns(remote);

            var storage = new Mock <IMetaDataStorage>();

            storage.AddLocalFile(Path, Id, Uuid);

            var fileEvent = new FileEvent(Mock.Of <IFileInfo>());
            var fetcher   = new RemoteObjectFetcher(session.Object, storage.Object);

            fetcher.Handle(fileEvent);

            session.Verify(s => s.GetObject(It.IsAny <string>(), It.IsAny <IOperationContext>()), Times.Never());
        }
示例#22
0
        public void OneRemoteFileRenamedAndContentHashIsAvailable()
        {
            byte[]   checksum         = new byte[20];
            string   type             = "SHA-1";
            string   oldFileName      = "fileName";
            string   newFileName      = "newfileName";
            string   fileId           = "fileId";
            DateTime lastModification = DateTime.UtcNow;
            var      localGuid        = Guid.NewGuid();
            var      oldLocalFile     = this.fsFactory.AddFile(Path.Combine(this.localRootPath, oldFileName));

            oldLocalFile.SetupLastWriteTimeUtc(lastModification);
            oldLocalFile.SetupGuid(localGuid);
            var storedFile = new MappedObject(oldFileName, fileId, MappedObjectType.File, this.remoteRootId, "changeToken")
            {
                Guid = localGuid,
                ChecksumAlgorithmName = type,
                LastChecksum          = checksum,
                LastLocalWriteTimeUtc = lastModification
            };

            this.localFolder.SetupFiles(oldLocalFile.Object);
            this.storage.SaveMappedObject(storedFile);
            var renamedRemoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, fileId, newFileName, this.remoteRootId, changeToken: "newChangeToken");

            renamedRemoteFile.SetupContentStreamHash(checksum, type);
            this.remoteFolder.SetupDescendants(renamedRemoteFile.Object);
            Assert.That(this.CreateCrawler().Handle(new StartNextSyncEvent()), Is.True);
            this.queue.Verify(
                q =>
                q.AddEvent(
                    It.Is <FileEvent>(
                        e =>
                        e.Remote == MetaDataChangeType.CHANGED &&
                        e.RemoteContent == ContentChangeType.NONE &&
                        e.Local == MetaDataChangeType.NONE &&
                        e.RemoteFile.Equals(renamedRemoteFile.Object))),
                Times.Once());
            this.VerifyThatCountOfAddedEventsIsLimitedTo(Times.Once());
            this.VerifyThatListenerHasBeenUsed();
        }
示例#23
0
        public void OneLocalFileRemoved()
        {
            var oldLocalFile = this.fsFactory.AddFile(Path.Combine(this.localRootPath, "oldFile"));

            oldLocalFile.Setup(f => f.Exists).Returns(false);
            var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, "oldFileId", "oldFile", this.remoteRootId, changeToken: "oldChange");
            var storedFile = new MappedObject("oldFile", "oldFileId", MappedObjectType.File, this.remoteRootId, "oldChange")
            {
                Guid = Guid.NewGuid()
            };

            this.storage.SaveMappedObject(storedFile);

            this.remoteFolder.SetupDescendants(remoteFile.Object);
            var crawler = this.CreateCrawler();

            Assert.That(crawler.Handle(new StartNextSyncEvent()), Is.True);
            this.queue.Verify(q => q.AddEvent(It.Is <FileEvent>(e => e.LocalFile != null && e.LocalFile.Equals(oldLocalFile.Object) && e.Local.Equals(MetaDataChangeType.DELETED))), Times.Once());
            this.VerifyThatCountOfAddedEventsIsLimitedTo(Times.Once());
            this.VerifyThatListenerHasBeenUsed();
        }
示例#24
0
        public void NoChangeOnExistingFileAndFolderCreatesNoEventsInQueue()
        {
            DateTime changeTime           = DateTime.UtcNow;
            string   changeToken          = "token";
            string   fileName             = "name";
            string   fileId               = "fileId";
            string   folderName           = "folder";
            string   folderId             = "folderId";
            Guid     folderGuid           = Guid.NewGuid();
            Guid     fileGuid             = Guid.NewGuid();
            var      remoteFile           = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, fileId, fileName, this.remoteRootId, changeToken: changeToken);
            var      existingRemoteFolder = MockOfIFolderUtil.CreateRemoteFolderMock(folderId, folderName, this.remoteRootPath + folderName, this.remoteRootId, changeToken);
            var      file = this.fsFactory.AddFile(Path.Combine(this.localRootPath, fileName), fileGuid);

            file.Setup(f => f.LastWriteTimeUtc).Returns(changeTime);
            var storedFile = new MappedObject(fileName, fileId, MappedObjectType.File, this.remoteRootId, changeToken)
            {
                Guid = fileGuid, LastLocalWriteTimeUtc = changeTime
            };

            this.storage.SaveMappedObject(storedFile);
            var folder = this.fsFactory.AddDirectory(Path.Combine(this.localRootPath, folderName), folderGuid);

            folder.Setup(f => f.LastWriteTimeUtc).Returns(changeTime);
            var storedFolder = new MappedObject(folderName, folderId, MappedObjectType.Folder, this.remoteRootId, changeToken)
            {
                Guid = folderGuid, LastLocalWriteTimeUtc = changeTime
            };

            this.storage.SaveMappedObject(storedFolder);
            this.remoteFolder.SetupDescendants(remoteFile.Object, existingRemoteFolder.Object);
            this.localFolder.SetupFilesAndDirectories(file.Object, folder.Object);

            var crawler = this.CreateCrawler();

            Assert.That(crawler.Handle(new StartNextSyncEvent()), Is.True);
            this.queue.Verify(q => q.AddEvent(It.Is <AbstractFolderEvent>(e => e.Local == MetaDataChangeType.NONE && e.Remote == MetaDataChangeType.NONE)), Times.Never());
            this.VerifyThatCountOfAddedEventsIsLimitedTo(Times.Never());
            this.VerifyThatListenerHasBeenUsed();
        }
示例#25
0
        private void RunSolverToChangeLocalCacheBeforeContinue(
            AbstractEnhancedSolver solver,
            ContentChangeType localContent  = ContentChangeType.NONE,
            ContentChangeType remoteContent = ContentChangeType.NONE)
        {
            this.SetupToChangeLocalCache();

            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.objectId, this.objectName, this.parentId, this.fileContent.Length, this.fileContent, this.changeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            solver.Solve(this.localFile.Object, remoteObject.Object, localContent, remoteContent);

            Assert.That(this.localFileLength, Is.EqualTo(this.fileContent.Length));
            this.cacheFile.Verify(f => f.Open(It.IsAny <FileMode>(), It.IsAny <FileAccess>(), It.IsAny <FileShare>()), Times.Exactly(3)); // first open in SetupToAbortThePreviousDownload, second open to validate checksum, third open to download
            this.cacheFile.Verify(f => f.Delete(), Times.Once());
            this.localFile.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Once());
            this.storage.VerifySavedMappedObject(MappedObjectType.File, this.objectId, this.objectName, this.parentId, this.changeToken, true, this.creationDate, this.creationDate, this.fileHash, this.fileContent.Length);
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(this.objectId), Times.Exactly(2));
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(this.objectId), Times.Once());
        }
        public void LocalAndRemoteFilesAreSavedAsEqualIfTheContentIsEqual()
        {
            var fileInfo  = new Mock <IFileInfo>();
            var parentDir = Mock.Of <IDirectoryInfo>(d => d.FullName == Path.GetTempPath());

            fileInfo.SetupAllProperties();
            fileInfo.Setup(f => f.FullName).Returns(this.path);
            fileInfo.Setup(f => f.Name).Returns(this.objectName);
            fileInfo.Setup(f => f.Directory).Returns(parentDir);
            fileInfo.Setup(f => f.Exists).Returns(true);
            byte[] content = Encoding.UTF8.GetBytes("content");
            fileInfo.SetupStream(content);
            byte[]           expectedHash = SHA1Managed.Create().ComputeHash(content);
            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.id, this.objectName, this.parentId, content.Length, content, this.lastChangeToken);

            remoteObject.SetupContentStreamHash(expectedHash);
            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            this.underTest.Solve(fileInfo.Object, remoteObject.Object);

            fileInfo.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Once());
            this.storage.VerifySavedMappedObject(MappedObjectType.File, this.id, this.objectName, this.parentId, this.lastChangeToken, true, this.creationDate, this.creationDate, expectedHash, content.Length);
        }
示例#27
0
        public void LocalFileContentChanged()
        {
            this.SetUpMocks();
            var newModificationDateOnServerAfterUpload = this.modificationDate.AddHours(1);
            int fileLength = 20;

            byte[] content      = new byte[fileLength];
            byte[] expectedHash = SHA1Managed.Create().ComputeHash(content);

            var localFile = this.CreateLocalFile(fileLength, this.modificationDate.AddMinutes(1));

            using (var uploadedContent = new MemoryStream()) {
                localFile.Setup(
                    f =>
                    f.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)).Returns(() => { return(new MemoryStream(content)); });
                var mappedObject = this.CreateMappedFile(this.modificationDate.AddMinutes(1), fileLength, new byte[20]);

                this.storage.AddMappedFile(mappedObject);
                var remoteFile = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.remoteId, this.objectName, this.parentId, fileLength, new byte[fileLength], this.oldChangeToken);
                remoteFile.Setup(r => r.SetContentStream(It.IsAny <IContentStream>(), true, true)).Callback <IContentStream, bool, bool>(
                    (s, o, r) =>
                    { s.Stream.CopyTo(uploadedContent);
                      remoteFile.Setup(f => f.LastModificationDate).Returns(newModificationDateOnServerAfterUpload);
                      remoteFile.Setup(f => f.ChangeToken).Returns(this.newChangeToken); });
                remoteFile.SetupUpdateModificationDate();

                this.underTest.Solve(localFile.Object, remoteFile.Object);

                remoteFile.VerifyUpdateLastModificationDate(localFile.Object.LastWriteTimeUtc);
                remoteFile.VerifySetContentStream();
                Assert.That(uploadedContent.ToArray(), Is.EqualTo(content));
                localFile.VerifyThatLocalFileObjectLastWriteTimeUtcIsNeverModified();
                this.manager.Verify(m => m.AddTransmission(It.IsAny <FileTransmissionEvent>()), Times.Once());
                this.VerifySavedFile(this.newChangeToken, localFile.Object.LastWriteTimeUtc, localFile.Object.LastWriteTimeUtc, expectedHash, fileLength);
            }
        }
示例#28
0
        public void RemoteDocumentChangedAndLocalFileGotChangedWhileDownloadingCreatesAConfictFile()
        {
            DateTime creationDate    = DateTime.UtcNow;
            string   fileName        = "a";
            string   path            = Path.Combine(Path.GetTempPath(), fileName);
            string   id              = "id";
            string   parentId        = "papa";
            string   lastChangeToken = "token";
            string   newChangeToken  = "newToken";
            string   confictFilePath = Path.Combine(Path.GetTempPath(), fileName + ".conflict");

            byte[] newContent     = Encoding.UTF8.GetBytes("content");
            byte[] oldContent     = Encoding.UTF8.GetBytes("older content");
            byte[] changedContent = Encoding.UTF8.GetBytes("change content");
            long   oldContentSize = oldContent.Length;
            long   newContentSize = newContent.Length;

            byte[] expectedHash = SHA1Managed.Create().ComputeHash(newContent);
            byte[] oldHash      = SHA1Managed.Create().ComputeHash(oldContent);
            var    mappedObject = new MappedObject(
                fileName,
                id,
                MappedObjectType.File,
                parentId,
                lastChangeToken,
                oldContentSize)
            {
                Guid = Guid.NewGuid(),
                LastLocalWriteTimeUtc  = new DateTime(0),
                LastRemoteWriteTimeUtc = new DateTime(0),
                LastChecksum           = oldHash
            };

            this.fsFactory.Setup(f => f.CreateConflictFileInfo(It.IsAny <IFileInfo>())).Returns(Mock.Of <IFileInfo>(i => i.FullName == confictFilePath));
            using (var changedContentStream = new MemoryStream(changedContent))
                using (var stream = new MemoryStream()) {
                    var backupFile = this.fsFactory.AddFile(Path.Combine(Path.GetTempPath(), fileName + ".bak.sync"), false);

                    this.storage.AddMappedFile(mappedObject, path);

                    Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, fileName, parentId, newContentSize, newContent, newChangeToken);
                    remoteObject.Setup(r => r.LastModificationDate).Returns(creationDate);

                    Mock <IFileInfo> localFile = new Mock <IFileInfo>();
                    localFile.SetupProperty(f => f.LastWriteTimeUtc, new DateTime(0));
                    localFile.Setup(f => f.FullName).Returns(path);
                    var cacheFile = this.fsFactory.SetupDownloadCacheFile(localFile.Object);
                    cacheFile.Setup(c => c.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)).Returns(stream);

                    this.SetupContentWithCallBack(remoteObject, newContent, fileName).Callback(
                        () =>
                    {
                        localFile.Setup(f => f.LastWriteTimeUtc).Returns(creationDate);
                    });

                    cacheFile.Setup(
                        c =>
                        c.Replace(localFile.Object, backupFile.Object, It.IsAny <bool>())).Returns(localFile.Object).Callback(
                        () =>
                        backupFile.Setup(
                            b =>
                            b.Open(FileMode.Open, FileAccess.Read, FileShare.None)).Returns(changedContentStream));

                    this.underTest.Solve(localFile.Object, remoteObject.Object, remoteContent: ContentChangeType.CHANGED);

                    this.storage.VerifySavedMappedObject(MappedObjectType.File, id, fileName, parentId, newChangeToken, true, creationDate, creationDate, expectedHash, newContent.Length);
                    Assert.That(localFile.Object.LastWriteTimeUtc, Is.EqualTo(creationDate));
                    cacheFile.Verify(c => c.Replace(localFile.Object, backupFile.Object, true), Times.Once());
                    backupFile.Verify(b => b.MoveTo(confictFilePath), Times.Once());
                    backupFile.Verify(b => b.Delete(), Times.Never());
                    backupFile.VerifySet(b => b.Uuid = null, Times.Once());
                }
        }
示例#29
0
        public void RemoteDocumentChangedAndSetUuidFailsOnLocalModificationDate()
        {
            DateTime creationDate    = DateTime.UtcNow;
            string   fileName        = "a";
            string   path            = Path.Combine(Path.GetTempPath(), fileName);
            string   id              = "id";
            string   parentId        = "papa";
            string   lastChangeToken = "token";
            string   newChangeToken  = "newToken";

            byte[] newContent     = Encoding.UTF8.GetBytes("content");
            byte[] oldContent     = Encoding.UTF8.GetBytes("older content");
            long   oldContentSize = oldContent.Length;
            long   newContentSize = newContent.Length;

            byte[] expectedHash = SHA1Managed.Create().ComputeHash(newContent);
            byte[] oldHash      = SHA1Managed.Create().ComputeHash(oldContent);
            var    mappedObject = new MappedObject(
                fileName,
                id,
                MappedObjectType.File,
                parentId,
                lastChangeToken,
                oldContentSize)
            {
                Guid = Guid.NewGuid(),
                LastLocalWriteTimeUtc  = new DateTime(0),
                LastRemoteWriteTimeUtc = new DateTime(0),
                LastChecksum           = oldHash
            };

            using (var oldContentStream = new MemoryStream(oldContent))
                using (var stream = new MemoryStream()) {
                    var backupFile = this.fsFactory.AddFile(Path.Combine(Path.GetTempPath(), fileName + ".bak.sync"), false);

                    this.storage.AddMappedFile(mappedObject, path);

                    Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, id, fileName, parentId, newContentSize, newContent, newChangeToken);
                    remoteObject.Setup(r => r.LastModificationDate).Returns(creationDate);

                    Mock <IFileInfo> localFile = new Mock <IFileInfo>();
                    localFile.SetupProperty(f => f.LastWriteTimeUtc, new DateTime(0));
                    localFile.Setup(f => f.FullName).Returns(path);
                    var cacheFile = this.fsFactory.SetupDownloadCacheFile(localFile.Object);
                    cacheFile.Setup(c => c.Open(FileMode.Create, FileAccess.Write, FileShare.None)).Returns(stream);
                    cacheFile.Setup(
                        c =>
                        c.Replace(localFile.Object, backupFile.Object, It.IsAny <bool>())).Returns(localFile.Object).Callback(
                        () =>
                        backupFile.Setup(
                            b =>
                            b.Open(FileMode.Open, FileAccess.Read, FileShare.None)).Returns(oldContentStream));
                    localFile.SetupSet(l => l.Uuid = It.IsAny <Guid?>()).Throws <RestoreModificationDateException>();

                    this.underTest.Solve(localFile.Object, remoteObject.Object, remoteContent: ContentChangeType.CHANGED);

                    this.storage.VerifySavedMappedObject(MappedObjectType.File, id, fileName, parentId, newChangeToken, true, creationDate, creationDate, expectedHash, newContent.Length);
                    Assert.That(localFile.Object.LastWriteTimeUtc, Is.EqualTo(creationDate));
                    this.queue.Verify(
                        q =>
                        q.AddEvent(It.Is <FileTransmissionEvent>(
                                       e =>
                                       e.Type == FileTransmissionType.DOWNLOAD_MODIFIED_FILE &&
                                       e.CachePath == cacheFile.Object.FullName &&
                                       e.Path == localFile.Object.FullName)),
                        Times.Once());
                    cacheFile.Verify(c => c.Replace(localFile.Object, backupFile.Object, true), Times.Once());
                    backupFile.Verify(b => b.Delete(), Times.Once());
                }
        }
        private void SetupToAbortThePreviousDownload(Mock <IFileInfo> fileInfo, Mock <IFileInfo> cacheFileInfo, byte[] content, out long lengthWrite)
        {
            var parentDir = Mock.Of <IDirectoryInfo>(d => d.FullName == Path.GetTempPath());

            fileInfo.SetupAllProperties();
            fileInfo.Setup(f => f.FullName).Returns(this.path);
            fileInfo.Setup(f => f.Name).Returns(this.objectName);
            fileInfo.Setup(f => f.Directory).Returns(parentDir);

            cacheFileInfo.SetupAllProperties();
            cacheFileInfo.Setup(f => f.FullName).Returns(this.path + ".sync");
            cacheFileInfo.Setup(f => f.Name).Returns(this.objectName + ".sync");
            cacheFileInfo.Setup(f => f.Directory).Returns(parentDir);
            cacheFileInfo.Setup(f => f.IsExtendedAttributeAvailable()).Returns(true);
            this.fsFactory.AddIFileInfo(cacheFileInfo.Object);

            this.transmissionStorage.Setup(f => f.SaveObject(It.IsAny <IFileTransmissionObject>())).Callback <IFileTransmissionObject>((o) => {
                this.transmissionStorage.Setup(f => f.GetObjectByRemoteObjectId(It.IsAny <string>())).Returns(o);
            });
            this.transmissionStorage.Setup(f => f.RemoveObjectByRemoteObjectId(It.IsAny <string>())).Callback(() => {
                this.transmissionStorage.Setup(f => f.GetObjectByRemoteObjectId(It.IsAny <string>())).Returns((IFileTransmissionObject)null);
            });

            var stream = new Mock <MemoryStream>();

            stream.SetupAllProperties();
            stream.Setup(f => f.CanWrite).Returns(true);    // required for System.Security.Cryptography.CryptoStream

            long length = 0;

            stream.Setup(f => f.Write(It.IsAny <byte[]>(), It.IsAny <int>(), It.IsAny <int>())).Callback((byte[] buffer, int offset, int count) => {
                if (length > 0)
                {
                    foreach (Transmission transmission in this.manager.ActiveTransmissions)
                    {
                        transmission.Abort();
                    }
                }

                length += count;
            });

            cacheFileInfo.Setup(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)).Returns(() => {
                cacheFileInfo.Setup(f => f.Exists).Returns(true);
                return(stream.Object);
            });

            Mock <IDocument> remoteObject = MockOfIDocumentUtil.CreateRemoteDocumentMock(null, this.id, this.objectName, this.parentId, content.Length, content, this.lastChangeToken);

            remoteObject.Setup(f => f.LastModificationDate).Returns((DateTime?)this.creationDate);

            Assert.Throws <AbortException>(() => this.underTest.Solve(fileInfo.Object, remoteObject.Object));

            cacheFileInfo.Verify(f => f.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None), Times.Once());
            cacheFileInfo.VerifySet(f => f.Uuid = It.Is <Guid?>(uuid => uuid != null && !uuid.Equals(Guid.Empty)), Times.Never());
            cacheFileInfo.Verify(f => f.MoveTo(this.path), Times.Never());
            fileInfo.VerifySet(d => d.LastWriteTimeUtc = It.Is <DateTime>(date => date.Equals(this.creationDate)), Times.Never());
            this.transmissionStorage.Verify(f => f.GetObjectByRemoteObjectId(It.IsAny <string>()), Times.Once());
            this.transmissionStorage.Verify(f => f.SaveObject(It.IsAny <IFileTransmissionObject>()), Times.AtLeastOnce());
            this.transmissionStorage.Verify(f => f.RemoveObjectByRemoteObjectId(It.IsAny <string>()), Times.Never());
            this.storage.Verify(f => f.SaveMappedObject(It.IsAny <IMappedObject>()), Times.Never());

            lengthWrite = length;
        }