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()); }
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()); }
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()); }
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()); }
/// <summary> /// Solve the specified situation by using the storage, localFile and remoteId. /// Uploads the file content if content has been changed. Otherwise simply saves the /// last modification date. /// </summary> /// <param name="localFileSystemInfo">Local filesystem info instance.</param> /// <param name="remoteId">Remote identifier or object.</param> /// <param name="localContent">Hint if the local content has been changed.</param> /// <param name="remoteContent">Information if the remote content has been changed.</param> public override void Solve( IFileSystemInfo localFileSystemInfo, IObjectId remoteId, ContentChangeType localContent = ContentChangeType.NONE, ContentChangeType remoteContent = ContentChangeType.NONE) { if (!localFileSystemInfo.Exists) { throw new ArgumentException("Given local path does not exists: " + localFileSystemInfo.FullName); } // Match local changes to remote changes and updated them remotely IMappedObject mappedObject = null; try { Guid?guid = localFileSystemInfo.Uuid; if (guid != null) { mappedObject = this.Storage.GetObjectByGuid((Guid)guid); } } catch (Exception) { } if (mappedObject == null) { mappedObject = this.Storage.GetObjectByLocalPath(localFileSystemInfo); } if (mappedObject == null) { throw new ArgumentException(string.Format("Could not find db entry for {0} => invoke crawl sync", localFileSystemInfo.FullName)); } if (mappedObject.LastChangeToken != (remoteId as ICmisObjectProperties).ChangeToken) { throw new ArgumentException(string.Format("remote {1} {0} has also been changed since last sync => invoke crawl sync", remoteId.Id, remoteId is IDocument ? "document" : "folder")); } IFileInfo localFile = localFileSystemInfo as IFileInfo; if (localFile != null && localFile.IsContentChangedTo(mappedObject, scanOnlyIfModificationDateDiffers: true)) { Logger.Debug(string.Format("\"{0}\" is different from {1}", localFile.FullName, mappedObject.ToString())); OperationsLogger.Debug(string.Format("Local file \"{0}\" has been changed", localFile.FullName)); var doc = remoteId as IDocument; try { mappedObject.LastChecksum = AbstractEnhancedSolver.UploadFile(localFile, doc, this.transmissionManager); } catch (Exception ex) { if (ex.InnerException is CmisPermissionDeniedException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: PermissionDenied", localFile.FullName)); return; } else if (ex.InnerException is CmisStorageException) { OperationsLogger.Warn(string.Format("Local changed file \"{0}\" has not been uploaded: StorageException", localFile.FullName), ex); return; } throw; } mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate; mappedObject.LastLocalWriteTimeUtc = localFile.LastWriteTimeUtc; mappedObject.LastContentSize = localFile.Length; OperationsLogger.Info(string.Format("Local changed file \"{0}\" has been uploaded", localFile.FullName)); } if (this.ServerCanModifyDateTimes) { try { if (remoteId is IDocument) { var doc = remoteId as IDocument; doc.UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = doc.LastModificationDate ?? localFileSystemInfo.LastWriteTimeUtc; } else if (remoteId is IFolder) { var folder = remoteId as IFolder; folder.UpdateLastWriteTimeUtc(localFileSystemInfo.LastWriteTimeUtc); mappedObject.LastRemoteWriteTimeUtc = folder.LastModificationDate ?? localFileSystemInfo.LastWriteTimeUtc; } } catch (CmisPermissionDeniedException) { Logger.Debug(string.Format("Locally changed modification date \"{0}\"is not uploaded to the server: PermissionDenied", localFileSystemInfo.LastWriteTimeUtc)); } } mappedObject.LastChangeToken = (remoteId as ICmisObjectProperties).ChangeToken; mappedObject.LastLocalWriteTimeUtc = localFileSystemInfo.LastWriteTimeUtc; this.Storage.SaveMappedObject(mappedObject); }