public void TestSetContentType() { string contentType = "contenttype"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFile(sourceDataInfo.RootNode, DMLibTestBase.FileName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); options.TransferItemModifier = (fileNode, transferItem) => { UploadOptions uploadOptions = new UploadOptions(); uploadOptions.ContentType = "contenttype"; transferItem.Options = uploadOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); FileNode destFileNode = result.DataInfo.RootNode.GetFileNode(DMLibTestBase.FileName); Test.Assert(contentType.Equals(destFileNode.ContentType), "Verify content type: {0}, expected {1}", destFileNode.ContentType, contentType); }
public void TestBlobDirectoryWithEncryptionScope() { DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddMultipleFilesNormalSize(sourceDataInfo.RootNode, DMLibTestBase.FileName); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; options.TransferItemModifier = (fileNode, transferItem) => { dynamic transferOptions = DefaultTransferDirectoryOptions; transferOptions.EncryptionScope = Test.Data.Get(DMLibTestConstants.DestEncryptionScope); transferOptions.Recursive = true; transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo); foreach (var fileNode in result.DataInfo.RootNode.EnumerateFileNodesRecursively()) { string destEncryptionScope = result.DataInfo.RootNode.FileNodes.First().EncryptionScope; Test.Assert(string.Equals(destEncryptionScope, Test.Data.Get(DMLibTestConstants.DestEncryptionScope)), "Encryption scope name in destination should be expected {0} == {1}", destEncryptionScope, Test.Data.Get(DMLibTestConstants.DestEncryptionScope)); } }
public void TestSingleFileShareSnapshots() { string snapshotFile = "snapshotFile"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); sourceDataInfo.IsFileShareSnapshot = true; DMLibDataHelper.AddMultipleFiles(sourceDataInfo.RootNode, snapshotFile, 3, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = false; // transfer with default options options.TransferItemModifier = (fileNode, transferItem) => { dynamic transferOptions = DefaultTransferOptions; transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // verify that Files in Share Snapshot is transferred Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); }
public void TestDirectorySetContentType() { string contentType = "contenttype/subtype"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); int[] fileSizes = new int[] { 1024, 1024, 1024 }; DMLibDataHelper.AddMultipleFilesDifferentSize(sourceDataInfo.RootNode, DMLibTestBase.FileName, fileSizes); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; options.TransferItemModifier = (fileNode, transferItem) => { dynamic uploadOptions = DefaultTransferDirectoryOptions; uploadOptions.ContentType = contentType; transferItem.Options = uploadOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); foreach (FileNode destFileNode in result.DataInfo.RootNode.FileNodes) { Test.Assert(contentType.Equals(destFileNode.ContentType), "Verify content type: {0}, expected {1}", destFileNode.ContentType, contentType); } }
public void TestSingleBlobWithEncryptionScope() { DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, DMLibTestBase.FileName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); options.TransferItemModifier = (fileNode, transferItem) => { dynamic transferOptions = DefaultTransferOptions; transferOptions.EncryptionScope = Test.Data.Get(DMLibTestConstants.DestEncryptionScope); transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo); string destEncryptionScope = result.DataInfo.RootNode.FileNodes.First().EncryptionScope; Test.Assert(string.Equals(destEncryptionScope, Test.Data.Get(DMLibTestConstants.DestEncryptionScope)), "Encryption scope name in destination should be expected {0} == {1}", destEncryptionScope, Test.Data.Get(DMLibTestConstants.DestEncryptionScope)); }
public void TestDirectoryNotIncludeSnapshots() { string snapshotFile1 = "snapshotFile1"; string snapshotFile2 = "snapshotFile2"; string snapshotFile3 = "snapshotFile3"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile1, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile2, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile3, 1024); // the 1st file has 1 snapshot FileNode fileNode1 = sourceDataInfo.RootNode.GetFileNode(snapshotFile1); fileNode1.SnapshotsCount = 1; // the 2nd file has 2 snapshots FileNode fileNode2 = sourceDataInfo.RootNode.GetFileNode(snapshotFile2); fileNode2.SnapshotsCount = 2; var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; // transfer with default options, or IncludeSnapshots = false options.TransferItemModifier = (fileNode, transferItem) => { dynamic dirOptions = DefaultTransferDirectoryOptions; dirOptions.Recursive = true; if (random.Next(0, 2) == 0) { Test.Info("Transfer directory with IncludeSnapshots=false"); dirOptions.IncludeSnapshots = false; } else { Test.Info("Transfer directory with defaullt IncludeSnapshots"); } transferItem.Options = dirOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // verify that only non-snapshot blobs are transferred DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); expectedDataInfo.RootNode.AddFileNode(fileNode1); expectedDataInfo.RootNode.AddFileNode(fileNode2); expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(snapshotFile3)); Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result."); }
public void TestFileShareSnapshotsCopyToBase() { int fileCount = 3; string snapshotFile = "snapshotFile"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); sourceDataInfo.IsFileShareSnapshot = true; DMLibDataHelper.AddMultipleFiles(sourceDataInfo.RootNode, snapshotFile, fileCount, 1024); SourceAdaptor.Cleanup(); SourceAdaptor.CreateIfNotExists(); SourceAdaptor.GenerateData(sourceDataInfo); CloudFileDataAdaptor fileAdaptor = (SourceAdaptor as CloudFileDataAdaptor); CloudFileDirectory SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, sourceDataInfo.RootNode) as CloudFileDirectory; CloudFileDirectory DestObject = fileAdaptor.fileHelper.FileClient.GetShareReference(fileAdaptor.ShareName).GetRootDirectoryReference(); // transfer File and finished succssfully Task <TransferStatus> task = TransferManager.CopyDirectoryAsync( SourceObject, DestObject, DMLibTestContext.IsAsync, new CopyDirectoryOptions() { Recursive = true }, new DirectoryTransferContext() { ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite }); Test.Assert(task.Wait(15 * 60 * 100), "Tansfer finished in time."); Test.Assert(task.Result.NumberOfFilesFailed == 0, "No Failed File."); Test.Assert(task.Result.NumberOfFilesSkipped == 0, "No Skipped File."); Test.Assert(task.Result.NumberOfFilesTransferred == fileCount, string.Format("Transferred file :{0} == {1}", task.Result.NumberOfFilesTransferred, fileCount)); // verify that Files in Share Snapshot is transferred IEnumerable <IListFileItem> sourceFiles = SourceObject.ListFilesAndDirectories(HelperConst.DefaultFileOptions); foreach (IListFileItem item in sourceFiles) { if (item is CloudFile) { CloudFile srcFile = item as CloudFile; CloudFile destFile = DestObject.GetFileReference(srcFile.Name); srcFile.FetchAttributes(); destFile.FetchAttributes(); Test.Assert(srcFile.Properties.ContentMD5 == destFile.Properties.ContentMD5, string.Format("File {0} MD5 :{1} == {2}", srcFile.Name, srcFile.Properties.ContentMD5, destFile.Properties.ContentMD5)); } } }
public void TestDirectorySetAttribute_Restart_Copy() { int bigFileSizeInKB = 5 * 1024; // 5 MB int smallFileSizeInKB = 1; // 1 KB int bigFileNum = 20; int smallFileNum = 50; string longString = StraightALongString; #if BINARY_SERIALIZATION longString = RandomLongString; #endif // For .Net core, blob readers cannot fetch contentType and etc with special chars. Dictionary <string, string> metadata = new Dictionary <string, string> { { MetadataKey1, longString } }; this.TestDirectorySetAttribute_Restart( bigFileSizeInKB, smallFileSizeInKB, bigFileNum, smallFileNum, bigFileDirNode => { DMLibDataHelper.AddMultipleFiles( bigFileDirNode, FileName, bigFileNum, bigFileSizeInKB, cacheControl: longString, contentDisposition: longString, contentEncoding: longString, contentLanguage: longString, contentType: longString, md5: invalidMD5, metadata: metadata); }, smallFileDirNode => { DMLibDataHelper.AddMultipleFiles( smallFileDirNode, FileName, smallFileNum, smallFileSizeInKB, cacheControl: longString, contentDisposition: longString, contentEncoding: longString, contentLanguage: longString, contentType: longString, md5: invalidMD5, metadata: metadata); } ); }
public void TestCheckContentMD5() { long fileSize = 10 * 1024 * 1024; string wrongMD5 = "wrongMD5"; string checkWrongMD5File = "checkWrongMD5File"; string notCheckWrongMD5File = "notCheckWrongMD5File"; string checkCorrectMD5File = "checkCorrectMD5File"; string notCheckCorrectMD5File = "notCheckCorrectMD5File"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, checkWrongMD5File, fileSize); FileNode tmpFileNode = sourceDataInfo.RootNode.GetFileNode(checkWrongMD5File); tmpFileNode.MD5 = wrongMD5; DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, notCheckWrongMD5File, fileSize); tmpFileNode = sourceDataInfo.RootNode.GetFileNode(notCheckWrongMD5File); tmpFileNode.MD5 = wrongMD5; DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, checkCorrectMD5File, fileSize); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, notCheckCorrectMD5File, fileSize); var options = new TestExecutionOptions <DMLibDataInfo>(); options.TransferItemModifier = (fileNode, transferItem) => { string fileName = fileNode.Name; DownloadOptions downloadOptions = new DownloadOptions(); if (fileName.Equals(checkWrongMD5File) || fileName.Equals(checkCorrectMD5File)) { downloadOptions.DisableContentMD5Validation = false; } else if (fileName.Equals(notCheckWrongMD5File) || fileName.Equals(notCheckCorrectMD5File)) { downloadOptions.DisableContentMD5Validation = true; } transferItem.Options = downloadOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); Test.Assert(result.Exceptions.Count == 1, "Verify there's one exception."); Exception exception = result.Exceptions[0]; Test.Assert(exception is InvalidOperationException, "Verify it's an invalid operation exception."); VerificationHelper.VerifyExceptionErrorMessage(exception, "The MD5 hash calculated from the downloaded data does not match the MD5 hash stored", checkWrongMD5File); }
// TODO: add more test cases public void TestUnsupportedDirection() { DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, DMLibTestBase.FileName, 1024); var result = this.ExecuteTestCase(sourceDataInfo, new TestExecutionOptions <DMLibDataInfo>()); Test.Assert(result.Exceptions.Count == 1, "Verify exception is thrown."); Exception exception = result.Exceptions[0]; if (DMLibCopyMethod.ServiceSideSyncCopy == DMLibTestContext.CopyMethod) { Test.Assert(exception is NotSupportedException, "Verify exception is NotSupportedException."); if (DMLibTestContext.DestType == DMLibDataType.CloudFile) { VerificationHelper.VerifyExceptionErrorMessage(exception, "Copying to Azure File Storage with service side synchronous copying is not supported."); } else { VerificationHelper.VerifyExceptionErrorMessage(exception, "Copying from Azure File Storage with service side synchronous copying is not supported."); } } else if (DMLibTestContext.SourceType == DMLibDataType.URI) { Test.Assert(exception is NotSupportedException, "Verify exception is NotSupportedException."); if (DMLibTestContext.DestType == DMLibDataType.CloudFile) { VerificationHelper.VerifyExceptionErrorMessage(exception, "Copying from uri to Azure File Storage synchronously is not supported"); } else { VerificationHelper.VerifyExceptionErrorMessage(exception, "Copying from uri to Azure Blob Storage synchronously is not supported"); } } else if (DMLibTestBase.IsCloudBlob(DMLibTestContext.SourceType) && DMLibTestBase.IsCloudBlob(DMLibTestContext.DestType)) { Test.Assert(exception is InvalidOperationException, "Verify exception is InvalidOperationException."); VerificationHelper.VerifyExceptionErrorMessage(exception, "Blob type of source and destination must be the same."); } else { Test.Assert(exception is InvalidOperationException, "Verify exception is InvalidOperationException."); VerificationHelper.VerifyExceptionErrorMessage(exception, string.Format("Copying from File Storage to {0} Blob Storage asynchronously is not supported.", MapBlobDataTypeToBlobType(DMLibTestContext.DestType))); } Test.Assert(DMLibDataHelper.Equals(new DMLibDataInfo(string.Empty), result.DataInfo), "Verify no file is transfered."); }
public void TestFileShareSnapshotsDest() { string failError1 = "Failed to validate destination"; string failError2 = "Cannot perform this operation on a share representing a snapshot."; //Prepare Data string snapshotFile = "snapshotFile"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFile(sourceDataInfo.RootNode, snapshotFile, 1024); SourceAdaptor.GenerateData(sourceDataInfo); DMLibDataInfo DestDataInfo = new DMLibDataInfo(string.Empty); DestDataInfo.IsFileShareSnapshot = true; DestAdaptor.GenerateData(DestDataInfo); CloudBlobDirectory SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, sourceDataInfo.RootNode) as CloudBlobDirectory; CloudFileDirectory DestObject = DestAdaptor.GetTransferObject(DestDataInfo.RootPath, DestDataInfo.RootNode) as CloudFileDirectory; // transfer File and failed with expected Error Task <TransferStatus> task = TransferManager.CopyDirectoryAsync( SourceObject, DestObject, DMLibTestContext.IsAsync, new CopyDirectoryOptions() { Recursive = true }, new DirectoryTransferContext() { ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite }); try { task.Wait(15 * 60 * 100); } catch (Exception e) { Test.Assert(e.InnerException.Message.Contains(failError1), "Tansfer Exception should contain:" + failError1); Test.Assert(e.InnerException.InnerException.Message.Contains(failError2), "Tansfer Exception should contain:" + failError2); } }
private void TestDelimiter(char delimiter) { Test.Info("Test delimiter: {0}", delimiter); DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); string fileName = DMLibTestBase.FolderName + delimiter + DMLibTestBase.FolderName + delimiter + DMLibTestBase.FileName; DMLibDataHelper.AddOneFile(sourceDataInfo.RootNode, fileName, 1); TransferContext context = new DirectoryTransferContext(); context.FileFailed += (sender, e) => { Test.Info(e.Exception.StackTrace); }; TestExecutionOptions <DMLibDataInfo> options = new TestExecutionOptions <DMLibDataInfo>() { IsDirectoryTransfer = true, TransferItemModifier = (node, item) => { dynamic dirOptions = DefaultTransferDirectoryOptions; dirOptions.Recursive = true; dirOptions.Delimiter = delimiter; item.Options = dirOptions; item.TransferContext = context; } }; TestResult <DMLibDataInfo> result = this.ExecuteTestCase(sourceDataInfo, options); DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); DirNode dirNode1 = new DirNode(FolderName); DirNode dirNode2 = new DirNode(FolderName); FileNode fileNode = sourceDataInfo.RootNode.GetFileNode(fileName).Clone(DMLibTestBase.FileName); dirNode2.AddFileNode(fileNode); dirNode1.AddDirNode(dirNode2); expectedDataInfo.RootNode.AddDirNode(dirNode1); VerificationHelper.VerifySingleTransferStatus(result, 1, 0, 0, null); VerificationHelper.VerifyTransferSucceed(result, expectedDataInfo); }
public void TestDirectoryIncludeSnapshots() { string snapshotFile1 = "snapshotFile1"; string snapshotFile2 = "snapshotFile2"; string snapshotFile3 = "snapshotFile3"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); // the 1st file has 1 snapshot DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile1, 1024); FileNode fileNode1 = sourceDataInfo.RootNode.GetFileNode(snapshotFile1); fileNode1.SnapshotsCount = 1; // the 2nd file has 2 snapshots DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile2, 1024); FileNode fileNode2 = sourceDataInfo.RootNode.GetFileNode(snapshotFile2); fileNode2.SnapshotsCount = 2; // the 3rd file has no snapshot DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, snapshotFile3, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; // transfer with IncludeSnapshots = true options.TransferItemModifier = (fileNode, transferItem) => { dynamic dirOptions = DefaultTransferDirectoryOptions; dirOptions.Recursive = true; dirOptions.IncludeSnapshots = true; transferItem.Options = dirOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // verify that snapshots are transferred Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); }
public void TestProgressHandlerTest() { long fileSize = 10 * 1024 * 1024; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, DMLibTestBase.FileName, fileSize); var options = new TestExecutionOptions <DMLibDataInfo>(); options.TransferItemModifier = (fileNode, transferItem) => { TransferContext transferContext = new SingleTransferContext(); ProgressChecker progressChecker = new ProgressChecker(1, fileNode.SizeInByte); transferContext.ProgressHandler = progressChecker.GetProgressHandler(); transferItem.TransferContext = transferContext; }; var result = this.ExecuteTestCase(sourceDataInfo, options); Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); }
public void DirectoryOverwriteDestination() { string destExistYName = "destExistY"; string destExistNName = "destExistN"; string destNotExistYName = "destNotExistY"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024); TransferContext transferContext = new DirectoryTransferContext(); transferContext.ShouldOverwriteCallbackAsync = async(source, destination) => { if (DMLibTestHelper.TransferInstanceToString(source).EndsWith(destExistNName)) { return(false); } else { return(true); } }; int skipCount = 0; int successCount = 0; transferContext.FileSkipped += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref skipCount); TransferException transferException = args.Exception as TransferException; Test.Assert(transferException != null, "Verify the exception is a TransferException"); VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination, "Skipped file", destExistNName); }; transferContext.FileTransferred += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref successCount); }; var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } options.TransferItemModifier = (fileNode, transferItem) => { transferItem.TransferContext = transferContext; dynamic transferOptions = DefaultTransferDirectoryOptions; transferOptions.Recursive = true; if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { transferOptions.PreserveSMBAttributes = true; transferOptions.PreserveSMBPermissions = true; } transferItem.Options = transferOptions; transferItem.TransferContext = transferContext; }; var result = this.ExecuteTestCase(sourceDataInfo, options); DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); if (DMLibTestContext.DestType != DMLibDataType.Stream) { expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName)); expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName)); expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName)); } else { expectedDataInfo = sourceDataInfo; } // Verify transfer result Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result."); // Verify exception if (DMLibTestContext.DestType != DMLibDataType.Stream) { VerificationHelper.VerifySingleTransferStatus(result, 2, 1, 0, 1024 * 2); Test.Assert(successCount == 2, "Verify success transfers"); Test.Assert(skipCount == 1, "Verify skipped transfer"); } else { VerificationHelper.VerifySingleTransferStatus(result, 3, 0, 0, 1024 * 3); Test.Assert(successCount == 3, "Very all transfers are success"); Test.Assert(skipCount == 0, "Very no transfer is skipped"); } if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { Helper.CompareSMBProperties(expectedDataInfo.RootNode, result.DataInfo.RootNode, true); Helper.CompareSMBPermissions( expectedDataInfo.RootNode, result.DataInfo.RootNode, PreserveSMBPermissions.Owner | PreserveSMBPermissions.Group | PreserveSMBPermissions.DACL | PreserveSMBPermissions.SACL); } }
private void TestAccessCondition(SourceOrDest sourceOrDest) { string eTag = "\"notmatch\""; AccessCondition accessCondition = new AccessCondition() { IfMatchETag = eTag }; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, DMLibTestBase.FileName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, DMLibTestBase.FileName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); if (sourceOrDest == SourceOrDest.Dest) { options.DestTransferDataInfo = destDataInfo; } options.TransferItemModifier = (fileNode, transferItem) => { dynamic transferOptions = DefaultTransferOptions; if (sourceOrDest == SourceOrDest.Source) { transferOptions.SourceAccessCondition = accessCondition; } else { transferOptions.DestinationAccessCondition = accessCondition; } transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); if (sourceOrDest == SourceOrDest.Dest) { Test.Assert(DMLibDataHelper.Equals(destDataInfo, result.DataInfo), "Verify no file is transferred."); } else { if (DMLibTestContext.DestType != DMLibDataType.Stream) { Test.Assert(DMLibDataHelper.Equals(new DMLibDataInfo(string.Empty), result.DataInfo), "Verify no file is transferred."); } else { foreach (var fileNode in result.DataInfo.EnumerateFileNodes()) { Test.Assert(fileNode.SizeInByte == 0, "Verify file {0} is empty", fileNode.Name); } } } // Verify TransferException if (result.Exceptions.Count != 1) { Test.Error("There should be exactly one exceptions."); return; } Exception exception = result.Exceptions[0]; #if DOTNET5_4 VerificationHelper.VerifyTransferException(exception, TransferErrorCode.Unknown); // Verify innner StorageException VerificationHelper.VerifyStorageException(exception.InnerException, (int)HttpStatusCode.PreconditionFailed, "The condition specified using HTTP conditional header(s) is not met."); #else VerificationHelper.VerifyTransferException(exception, TransferErrorCode.Unknown); // Verify innner StorageException VerificationHelper.VerifyStorageException(exception.InnerException, (int)HttpStatusCode.PreconditionFailed, "The condition specified using HTTP conditional header(s) is not met."); #endif }
public void OverwriteDestination() { string destExistYName = "destExistY"; string destExistNName = "destExistN"; string destNotExistYName = "destNotExistY"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } options.TransferItemModifier = (fileNode, transferItem) => { string fileName = fileNode.Name; TransferContext transferContext = new TransferContext(); if (fileName.Equals(destExistYName)) { transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackY(); } else if (fileName.Equals(destExistNName)) { transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackN(); } else if (fileName.Equals(destNotExistYName)) { transferContext.OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackY(); } transferItem.TransferContext = transferContext; }; var result = this.ExecuteTestCase(sourceDataInfo, options); DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); if (DMLibTestContext.DestType != DMLibDataType.Stream) { expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName)); expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName)); expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName)); } else { expectedDataInfo = sourceDataInfo; } // Verify transfer result Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result."); // Verify exception if (DMLibTestContext.DestType != DMLibDataType.Stream) { Test.Assert(result.Exceptions.Count == 1, "Verify there's only one exceptions."); TransferException transferException = result.Exceptions[0] as TransferException; Test.Assert(transferException != null, "Verify the exception is a TransferException"); VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination, "Skiped file", destExistNName); } }
public void DirectoryOverwriteDestination() { string destExistYName = "destExistY"; string destExistNName = "destExistN"; string destNotExistYName = "destNotExistY"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024); TransferContext transferContext = new TransferContext(); transferContext.OverwriteCallback = (string sourcePath, string destinationPath) => { if (sourcePath.EndsWith(destExistNName)) { return(false); } else { return(true); } }; int skipCount = 0; int successCount = 0; transferContext.FileSkipped += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref skipCount); TransferException transferException = args.Exception as TransferException; Test.Assert(transferException != null, "Verify the exception is a TransferException"); VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination, "Skiped file", destExistNName); }; transferContext.FileTransferred += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref successCount); }; var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } options.TransferItemModifier = (fileNode, transferItem) => { transferItem.TransferContext = transferContext; dynamic transferOptions = DefaultTransferDirectoryOptions; transferOptions.Recursive = true; transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); if (DMLibTestContext.DestType != DMLibDataType.Stream) { expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName)); expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName)); expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName)); } else { expectedDataInfo = sourceDataInfo; } // Verify transfer result Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result."); // Verify exception if (DMLibTestContext.DestType != DMLibDataType.Stream) { Test.Assert(successCount == 2, "Verify success transfers"); Test.Assert(skipCount == 1, "Verify skipped transfer"); } else { Test.Assert(successCount == 3, "Very all transfers are success"); Test.Assert(skipCount == 0, "Very no transfer is skipped"); } }
public void TestDirectorySetAttribute_Restart_Upload() { int bigFileSizeInKB = 5 * 1024; // 5 MB int smallFileSizeInKB = 1; // 1 KB int bigFileNum = 20; int smallFileNum = 50; this.TestDirectorySetAttribute_Restart( bigFileSizeInKB, smallFileSizeInKB, bigFileNum, smallFileNum, bigFileDirNode => { DMLibDataHelper.AddMultipleFiles( bigFileDirNode, FileName, bigFileNum, bigFileSizeInKB); }, smallFileDirNode => { DMLibDataHelper.AddMultipleFiles( smallFileDirNode, FileName, smallFileNum, smallFileSizeInKB); }, async(destObj) => { dynamic destCloudObj = destObj; destCloudObj.Properties.ContentType = RandomLongString; destCloudObj.Properties.CacheControl = RandomLongString; destCloudObj.Properties.ContentDisposition = RandomLongString; destCloudObj.Properties.ContentEncoding = RandomLongString; destCloudObj.Properties.ContentLanguage = RandomLongString; destCloudObj.Properties.ContentType = RandomLongString; destCloudObj.Properties.ContentMD5 = invalidMD5; destCloudObj.Metadata.Remove(MetadataKey1); destCloudObj.Metadata.Add(MetadataKey1, RandomLongString); }, sourceDataInfo => { foreach (var fileNode in sourceDataInfo.EnumerateFileNodes()) { fileNode.ContentType = RandomLongString; fileNode.CacheControl = RandomLongString; fileNode.ContentDisposition = RandomLongString; fileNode.ContentEncoding = RandomLongString; fileNode.ContentLanguage = RandomLongString; fileNode.ContentType = RandomLongString; fileNode.MD5 = invalidMD5; fileNode.Metadata = new Dictionary <string, string> { { MetadataKey1, RandomLongString } }; } } ); }
private void UploadFromStreamTest(DMLibDataType destType, long[] variedSourceLength, int?blockSize, bool seekable, bool fixedSized) { DataAdaptor <DMLibDataInfo> sourceAdaptor = GetSourceAdaptor(DMLibDataType.Stream); DataAdaptor <DMLibDataInfo> destAdaptor = GetDestAdaptor(destType); DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); foreach (long fileSizeInByte in variedSourceLength) { sourceDataInfo.RootNode.AddFileNode(new FileNode($"{FileName}_{fileSizeInByte}") { SizeInByte = fileSizeInByte, }); } sourceAdaptor.GenerateData(sourceDataInfo); destAdaptor.CreateIfNotExists(); List <TransferItem> uploadItems = new List <TransferItem>(); foreach (long fileSizeInByte in variedSourceLength) { string fileName = $"{FileName}_{fileSizeInByte}"; FileNode fileNode = sourceDataInfo.RootNode.GetFileNode(fileName); uploadItems.Add(new TransferItem() { SourceObject = new DMLibTestStream(sourceAdaptor.GetTransferObject(string.Empty, fileNode) as FileStream, seekable, fixedSized), DestObject = destAdaptor.GetTransferObject(string.Empty, fileNode), SourceType = DMLibDataType.Stream, DestType = destType, IsServiceCopy = false }); } // Execution var result = this.RunTransferItems( uploadItems, new TestExecutionOptions <DMLibDataInfo>() { DisableDestinationFetch = true, BlockSize = blockSize.HasValue ? blockSize.Value : 4 * 1024 * 1024 }); if (!fixedSized && (destType == DMLibDataType.PageBlob || destType == DMLibDataType.CloudFile)) { Test.Assert(result.Exceptions.Count == 1 && result.Exceptions[0].Message.Contains("Source must be fixed size"), "Verify error is expected."); } else { // Verify all files are transfered successfully Test.Assert(result.Exceptions.Count == 0, "Verify no exception occurs."); DMLibDataInfo destDataInfo = destAdaptor.GetTransferDataInfo(string.Empty); foreach (FileNode destFileNode in destDataInfo.EnumerateFileNodes()) { FileNode sourceFileNode = sourceDataInfo.RootNode.GetFileNode(destFileNode.Name); Test.Assert(DMLibDataHelper.Equals(sourceFileNode, destFileNode), "Verify transfer result."); } } sourceAdaptor.Cleanup(); destAdaptor.Cleanup(); }
public void OverwriteDestination() { string destExistYName = "destExistY"; string destExistNName = "destExistN"; string destNotExistYName = "destNotExistY"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistNName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistYName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistYName, 1024); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistNName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } options.TransferItemModifier = (fileNode, transferItem) => { string fileName = fileNode.Name; TransferContext transferContext = new SingleTransferContext(); if (fileName.Equals(destExistYName)) { transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY(); } else if (fileName.Equals(destExistNName)) { transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackN(); } else if (fileName.Equals(destNotExistYName)) { transferContext.ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY(); } transferItem.TransferContext = transferContext; dynamic transferOptions = DefaultTransferOptions; if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { transferOptions.PreserveSMBAttributes = true; transferOptions.PreserveSMBPermissions = true; } transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); DMLibDataInfo expectedDataInfo = new DMLibDataInfo(string.Empty); if (DMLibTestContext.DestType != DMLibDataType.Stream) { expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destExistYName)); expectedDataInfo.RootNode.AddFileNode(destDataInfo.RootNode.GetFileNode(destExistNName)); expectedDataInfo.RootNode.AddFileNode(sourceDataInfo.RootNode.GetFileNode(destNotExistYName)); } else { expectedDataInfo = sourceDataInfo; } // Verify transfer result Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, result.DataInfo), "Verify transfer result."); // Verify exception if (DMLibTestContext.DestType != DMLibDataType.Stream) { Test.Assert(result.Exceptions.Count == 1, "Verify there's only one exceptions."); TransferException transferException = result.Exceptions[0] as TransferException; Test.Assert(transferException != null, "Verify the exception is a TransferException"); VerificationHelper.VerifyTransferException(transferException, TransferErrorCode.NotOverwriteExistingDestination, "Skipped file", destExistNName); } if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { Helper.CompareSMBProperties(expectedDataInfo.RootNode, result.DataInfo.RootNode, true); Helper.CompareSMBPermissions( expectedDataInfo.RootNode, result.DataInfo.RootNode, PreserveSMBPermissions.Owner | PreserveSMBPermissions.Group | PreserveSMBPermissions.DACL | PreserveSMBPermissions.SACL); } }
public void TestDirectoryCheckContentMD5() { long fileSize = 5 * 1024 * 1024; long totalSize = fileSize * 4; string wrongMD5 = "wrongMD5"; string checkWrongMD5File = "checkWrongMD5File"; string checkCorrectMD5File = "checkCorrectMD5File"; string notCheckWrongMD5File = "notCheckWrongMD5File"; string notCheckCorrectMD5File = "notCheckCorrectMD5File"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DirNode checkMD5Folder = new DirNode("checkMD5"); DMLibDataHelper.AddOneFileInBytes(checkMD5Folder, checkWrongMD5File, fileSize); DMLibDataHelper.AddOneFileInBytes(checkMD5Folder, checkCorrectMD5File, fileSize); sourceDataInfo.RootNode.AddDirNode(checkMD5Folder); DirNode notCheckMD5Folder = new DirNode("notCheckMD5"); DMLibDataHelper.AddOneFileInBytes(notCheckMD5Folder, notCheckWrongMD5File, fileSize); DMLibDataHelper.AddOneFileInBytes(notCheckMD5Folder, notCheckCorrectMD5File, fileSize); sourceDataInfo.RootNode.AddDirNode(notCheckMD5Folder); FileNode tmpFileNode = checkMD5Folder.GetFileNode(checkWrongMD5File); tmpFileNode.MD5 = wrongMD5; tmpFileNode = notCheckMD5Folder.GetFileNode(notCheckWrongMD5File); tmpFileNode.MD5 = wrongMD5; SourceAdaptor.GenerateData(sourceDataInfo); TransferEventChecker eventChecker = new TransferEventChecker(); TransferContext context = new TransferContext(); eventChecker.Apply(context); bool failureReported = false; context.FileFailed += (sender, args) => { if (args.Exception != null) { failureReported = args.Exception.Message.Contains(checkWrongMD5File); } }; ProgressChecker progressChecker = new ProgressChecker(4, totalSize, 3, 1, 0, totalSize); context.ProgressHandler = progressChecker.GetProgressHandler(); List <Exception> transferExceptions = new List <Exception>(); context.FileFailed += (eventSource, eventArgs) => { transferExceptions.Add(eventArgs.Exception); }; TransferItem checkMD5Item = new TransferItem() { SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), DestObject = DestAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), IsDirectoryTransfer = true, SourceType = DMLibTestContext.SourceType, DestType = DMLibTestContext.DestType, IsServiceCopy = DMLibTestContext.IsAsync, TransferContext = context, Options = new DownloadDirectoryOptions() { DisableContentMD5Validation = false, Recursive = true, }, }; TransferItem notCheckMD5Item = new TransferItem() { SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, notCheckMD5Folder), DestObject = DestAdaptor.GetTransferObject(sourceDataInfo.RootPath, notCheckMD5Folder), IsDirectoryTransfer = true, SourceType = DMLibTestContext.SourceType, DestType = DMLibTestContext.DestType, IsServiceCopy = DMLibTestContext.IsAsync, TransferContext = context, Options = new DownloadDirectoryOptions() { DisableContentMD5Validation = true, Recursive = true, }, }; var testResult = this.RunTransferItems(new List <TransferItem>() { checkMD5Item, notCheckMD5Item }, new TestExecutionOptions <DMLibDataInfo>()); DMLibDataInfo expectedDataInfo = sourceDataInfo.Clone(); expectedDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode(checkWrongMD5File); expectedDataInfo.RootNode.GetDirNode(notCheckMD5Folder.Name).DeleteFileNode(notCheckWrongMD5File); DMLibDataInfo actualDataInfo = testResult.DataInfo; actualDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode(checkWrongMD5File); actualDataInfo.RootNode.GetDirNode(notCheckMD5Folder.Name).DeleteFileNode(notCheckWrongMD5File); Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, actualDataInfo), "Verify transfer result."); Test.Assert(failureReported, "Verify md5 check failure is reported."); VerificationHelper.VerifyFinalProgress(progressChecker, 3, 0, 1); if (testResult.Exceptions.Count != 0 || transferExceptions.Count != 1) { Test.Error("Expect one exception but actually no exception is thrown."); } else { VerificationHelper.VerifyExceptionErrorMessage(transferExceptions[0], new string[] { "The MD5 hash calculated from the downloaded data does not match the MD5 hash stored in the property of source" }); } }
public void DirectoryForceOverwriteTest() { string destExistName = "destExist"; string destNotExistName = "destNotExist"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistName, 1024); TransferContext transferContext = new DirectoryTransferContext(); transferContext.ShouldOverwriteCallback = TransferContext.ForceOverwrite; int skipCount = 0; int successCount = 0; transferContext.FileSkipped += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref skipCount); }; transferContext.FileTransferred += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref successCount); }; var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } if (IsCloudService(DMLibTestContext.DestType)) { SharedAccessPermissions permissions; if (DMLibTestContext.IsAsync) { permissions = SharedAccessPermissions.Write | SharedAccessPermissions.Read; } else { permissions = SharedAccessPermissions.Write; } StorageCredentials destSAS = new StorageCredentials(DestAdaptor.GenerateSAS(permissions, (int)new TimeSpan(1, 0, 0, 0).TotalSeconds)); options.DestCredentials = destSAS; } options.TransferItemModifier = (fileNode, transferItem) => { transferItem.TransferContext = transferContext; dynamic transferOptions = DefaultTransferDirectoryOptions; transferOptions.Recursive = true; transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // Verify transfer result Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); VerificationHelper.VerifySingleTransferStatus(result, 2, 0, 0, 1024 * 2); Test.Assert(successCount == 2, "Verify success transfers"); Test.Assert(skipCount == 0, "Verify skipped transfer"); }
private void TestDirectoryCheckContentMD5StreamResume(bool checkMD5) { long fileSize = 5 * 1024; int fileCountMulti = 32; long totalSize = fileSize * 4 * fileCountMulti; string wrongMD5 = "wrongMD5"; string wrongMD5File = "wrongMD5File"; string correctMD5File = "correctMD5File"; // Prepare data for transfer items with checkMD5 DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DirNode checkMD5Folder = new DirNode(checkMD5 ? "checkMD5" : "notCheckMD5"); for (int i = 0; i < fileCountMulti; ++i) { var wrongMD5FileNode = new FileNode($"{wrongMD5File}_{i}") { SizeInByte = fileSize, MD5 = wrongMD5 }; checkMD5Folder.AddFileNode(wrongMD5FileNode); DMLibDataHelper.AddOneFileInBytes(checkMD5Folder, $"{correctMD5File}_{i}", fileSize); } sourceDataInfo.RootNode.AddDirNode(checkMD5Folder); SourceAdaptor.GenerateData(sourceDataInfo); DestAdaptor.Cleanup(); TransferEventChecker eventChecker = new TransferEventChecker(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); using (var resumeStream = new MemoryStream()) { TransferContext context = new DirectoryTransferContext(resumeStream); eventChecker.Apply(context); ProgressChecker progressChecker = new ProgressChecker(2 * fileCountMulti, totalSize, checkMD5 ? fileCountMulti : 2 * fileCountMulti, null, 0, totalSize); context.ProgressHandler = progressChecker.GetProgressHandler(); List <Exception> transferExceptions = new List <Exception>(); TransferItem checkMD5Item = new TransferItem() { SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), DestObject = DestAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), IsDirectoryTransfer = true, SourceType = DMLibTestContext.SourceType, DestType = DMLibTestContext.DestType, CopyMethod = DMLibTestContext.CopyMethod.ToCopyMethod(), TransferContext = context, Options = new DownloadDirectoryOptions() { DisableContentMD5Validation = !checkMD5, Recursive = true, }, CancellationToken = cancellationTokenSource.Token, }; var executionOption = new TestExecutionOptions <DMLibDataInfo>(); executionOption.AfterAllItemAdded = () => { // Wait until there are data transferred if (!progressChecker.DataTransferred.WaitOne(30000)) { Test.Error("No progress in 30s."); } // Cancel the transfer and store the second checkpoint cancellationTokenSource.Cancel(); }; executionOption.LimitSpeed = true; var testResult = this.RunTransferItems(new List <TransferItem>() { checkMD5Item }, executionOption); if (null != testResult.Exceptions) { foreach (var exception in testResult.Exceptions) { Test.Info("Got exception during transferring. {0}", exception); } } eventChecker = new TransferEventChecker(); resumeStream.Position = 0; context = new DirectoryTransferContext(resumeStream); eventChecker.Apply(context); bool failureReported = false; context.FileFailed += (sender, args) => { if (args.Exception != null) { failureReported = args.Exception.Message.Contains(wrongMD5File); } transferExceptions.Add(args.Exception); }; progressChecker.Reset(); context.ProgressHandler = progressChecker.GetProgressHandler(); checkMD5Item = checkMD5Item.Clone(); checkMD5Item.TransferContext = context; testResult = this.RunTransferItems(new List <TransferItem>() { checkMD5Item }, new TestExecutionOptions <DMLibDataInfo>()); DMLibDataInfo expectedDataInfo = sourceDataInfo.Clone(); DMLibDataInfo actualDataInfo = testResult.DataInfo; for (int i = 0; i < fileCountMulti; ++i) { expectedDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode($"{wrongMD5File}_{i}"); actualDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode($"{wrongMD5File}_{i}"); } Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, actualDataInfo), "Verify transfer result."); Test.Assert(checkMD5 ? failureReported : !failureReported, "Verify md5 check failure is expected."); VerificationHelper.VerifyFinalProgress(progressChecker, checkMD5 ? fileCountMulti : 2 * fileCountMulti, 0, checkMD5 ? fileCountMulti : 0); if (checkMD5) { if (testResult.Exceptions.Count != 0 || transferExceptions.Count != fileCountMulti) { Test.Error("Expect one exception but actually no exception is thrown."); } else { for (int i = 0; i < fileCountMulti; ++i) { VerificationHelper.VerifyExceptionErrorMessage(transferExceptions[i], new string[] { "The MD5 hash calculated from the downloaded data does not match the MD5 hash stored in the property of source" }); } } } else { Test.Assert(testResult.Exceptions.Count == 0, "Should no exception thrown out when disabling check md5"); } } }
private void DownloadToMultipleStreams(DMLibDataType sourceType, long fileSize, int blockSize = 0) { DataAdaptor <DMLibDataInfo> sourceAdaptor = GetSourceAdaptor(sourceType); DataAdaptor <DMLibDataInfo> destAdaptor1 = GetDestAdaptor(DMLibDataType.Stream); Test.Info("SourceType: {0}, filesize {1}, blocksize {2}", sourceType, fileSize, blockSize); DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); long fileSizeInByte = fileSize; sourceDataInfo.RootNode.AddFileNode(new FileNode(FileName) { SizeInByte = fileSizeInByte, }); sourceAdaptor.GenerateData(sourceDataInfo); destAdaptor1.CreateIfNotExists(); List <TransferItem> downloadItems = new List <TransferItem>(); FileNode fileNode = sourceDataInfo.RootNode.GetFileNode(FileName); int streamCount = random.Next(2, 6); for (int i = 0; i < streamCount; ++i) { downloadItems.Add(new TransferItem() { SourceObject = sourceAdaptor.GetTransferObject(string.Empty, fileNode), DestObject = (destAdaptor1 as LocalDataAdaptor).GetTransferObject(string.Empty, $"{FileName}_{i}"), SourceType = sourceType, DestType = DMLibDataType.Stream, IsServiceCopy = false }); } var options = new TestExecutionOptions <DMLibDataInfo>() { DisableDestinationFetch = true, }; if (0 != blockSize) { options.BlockSize = blockSize; } // Execution var result = this.RunTransferItems( downloadItems, options); // Verify all files are transfered successfully Test.Assert(result.Exceptions.Count == 0, "Verify no exception occurs."); DMLibDataInfo destDataInfo = destAdaptor1.GetTransferDataInfo(string.Empty); foreach (FileNode destFileNode in destDataInfo.EnumerateFileNodes()) { var toBeValidateFileNode = destFileNode.Clone(FileName); FileNode sourceFileNode = sourceDataInfo.RootNode.GetFileNode(FileName); Test.Assert(DMLibDataHelper.Equals(sourceFileNode, toBeValidateFileNode), "Verify transfer result."); } sourceAdaptor.Cleanup(); destAdaptor1.Cleanup(); }
public void ForceOverwriteTest() { string destExistName = "destExist"; string destNotExistName = "destNotExist"; DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destExistName, 1024); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, destNotExistName, 1024); DMLibDataInfo destDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(destDataInfo.RootNode, destExistName, 1024); TransferContext transferContext = new SingleTransferContext(); transferContext.ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite; int skipCount = 0; int successCount = 0; transferContext.FileSkipped += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref skipCount); }; transferContext.FileTransferred += (object sender, TransferEventArgs args) => { Interlocked.Increment(ref successCount); }; var options = new TestExecutionOptions <DMLibDataInfo>(); if (DMLibTestContext.DestType != DMLibDataType.Stream) { options.DestTransferDataInfo = destDataInfo; } if (IsCloudService(DMLibTestContext.DestType)) { SharedAccessPermissions permissions; if (DMLibTestContext.CopyMethod == DMLibCopyMethod.ServiceSideAsyncCopy) { permissions = SharedAccessPermissions.Write | SharedAccessPermissions.Read; } else { permissions = SharedAccessPermissions.Write; } StorageCredentials destSAS = new StorageCredentials(DestAdaptor.GenerateSAS(permissions, (int)new TimeSpan(1, 0, 0, 0).TotalSeconds)); options.DestCredentials = destSAS; } options.TransferItemModifier = (fileNode, transferItem) => { transferItem.TransferContext = transferContext; dynamic transferOptions = DefaultTransferOptions; if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { transferOptions.PreserveSMBAttributes = true; transferOptions.PreserveSMBPermissions = true; } transferItem.Options = transferOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // Verify transfer result Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); Test.Assert(successCount == 2, "Verify success transfers"); Test.Assert(skipCount == 0, "Verify skipped transfer"); if (DMLibTestContext.SourceType == DMLibDataType.CloudFile && DMLibTestContext.DestType == DMLibDataType.CloudFile) { Helper.CompareSMBProperties(sourceDataInfo.RootNode, result.DataInfo.RootNode, true); Helper.CompareSMBPermissions( sourceDataInfo.RootNode, result.DataInfo.RootNode, PreserveSMBPermissions.Owner | PreserveSMBPermissions.Group | PreserveSMBPermissions.DACL | PreserveSMBPermissions.SACL); } }
public void TestDirectorySetAttribute_Restart_Upload() { int bigFileSizeInKB = 5 * 1024; // 5 MB int smallFileSizeInKB = 1; // 1 KB int bigFileNum = 20; int smallFileNum = 50; this.TestDirectorySetAttribute_Restart( bigFileSizeInKB, smallFileSizeInKB, bigFileNum, smallFileNum, bigFileDirNode => { DMLibDataHelper.AddMultipleFiles( bigFileDirNode, FileName, bigFileNum, bigFileSizeInKB); }, smallFileDirNode => { DMLibDataHelper.AddMultipleFiles( smallFileDirNode, FileName, smallFileNum, smallFileSizeInKB); }, async(sourceObj, destObj) => { long sourceLength = 0; string path = sourceObj as string; if (null == path) { Test.Error("Source should be a local file path."); } else { sourceLength = new System.IO.FileInfo(path).Length; } dynamic destCloudObj = destObj; destCloudObj.Properties.ContentType = RandomLongString; destCloudObj.Properties.CacheControl = RandomLongString; destCloudObj.Properties.ContentDisposition = RandomLongString; destCloudObj.Properties.ContentEncoding = RandomLongString; destCloudObj.Properties.ContentLanguage = RandomLongString; destCloudObj.Properties.ContentType = RandomLongString; destCloudObj.Properties.ContentMD5 = invalidMD5; destCloudObj.Metadata.Remove(MetadataKey1); destCloudObj.Metadata.Add(MetadataKey1, RandomLongString); destCloudObj.Metadata["filelength"] = sourceLength.ToString(); }, sourceDataInfo => { foreach (var fileNode in sourceDataInfo.EnumerateFileNodes()) { fileNode.ContentType = RandomLongString; fileNode.CacheControl = RandomLongString; fileNode.ContentDisposition = RandomLongString; fileNode.ContentEncoding = RandomLongString; fileNode.ContentLanguage = RandomLongString; fileNode.ContentType = RandomLongString; fileNode.MD5 = invalidMD5; fileNode.Metadata = new Dictionary <string, string> { { MetadataKey1, RandomLongString } }; fileNode.Metadata["filelength"] = fileNode.SizeInByte.ToString(); } } ); }
public void TestDirectoryCheckContentMD5Resume() { long fileSize = 5 * 1024; int fileCountMulti = 32; long totalSize = fileSize * 4 * fileCountMulti; string wrongMD5 = "wrongMD5"; string checkWrongMD5File = "checkWrongMD5File"; string checkCorrectMD5File = "checkCorrectMD5File"; string notCheckWrongMD5File = "notCheckWrongMD5File"; string notCheckCorrectMD5File = "notCheckCorrectMD5File"; // Prepare data for transfer items with checkMD5 DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DirNode checkMD5Folder = new DirNode("checkMD5"); for (int i = 0; i < fileCountMulti; ++i) { var wrongMD5FileNode = new FileNode($"{checkWrongMD5File}_{i}") { SizeInByte = fileSize, MD5 = wrongMD5 }; checkMD5Folder.AddFileNode(wrongMD5FileNode); DMLibDataHelper.AddOneFileInBytes(checkMD5Folder, $"{checkCorrectMD5File}_{i}", fileSize); } sourceDataInfo.RootNode.AddDirNode(checkMD5Folder); // Prepare data for transfer items with disabling MD5 check DirNode notCheckMD5Folder = new DirNode("notCheckMD5"); for (int i = 0; i < fileCountMulti; ++i) { var wrongMD5FileNode = new FileNode($"{notCheckWrongMD5File}_{i}") { SizeInByte = fileSize, MD5 = wrongMD5 }; notCheckMD5Folder.AddFileNode(wrongMD5FileNode); DMLibDataHelper.AddOneFileInBytes(notCheckMD5Folder, $"{notCheckCorrectMD5File}_{i}", fileSize); } sourceDataInfo.RootNode.AddDirNode(notCheckMD5Folder); SourceAdaptor.GenerateData(sourceDataInfo); TransferEventChecker eventChecker = new TransferEventChecker(); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); TransferContext context = new DirectoryTransferContext(); eventChecker.Apply(context); ProgressChecker progressChecker = new ProgressChecker(4 * fileCountMulti, totalSize, 3 * fileCountMulti, null, 0, totalSize); context.ProgressHandler = progressChecker.GetProgressHandler(); List <Exception> transferExceptions = new List <Exception>(); TransferItem checkMD5Item = new TransferItem() { SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), DestObject = DestAdaptor.GetTransferObject(sourceDataInfo.RootPath, checkMD5Folder), IsDirectoryTransfer = true, SourceType = DMLibTestContext.SourceType, DestType = DMLibTestContext.DestType, IsServiceCopy = DMLibTestContext.IsAsync, TransferContext = context, Options = new DownloadDirectoryOptions() { DisableContentMD5Validation = false, Recursive = true, }, CancellationToken = cancellationTokenSource.Token, }; TransferItem notCheckMD5Item = new TransferItem() { SourceObject = SourceAdaptor.GetTransferObject(sourceDataInfo.RootPath, notCheckMD5Folder), DestObject = DestAdaptor.GetTransferObject(sourceDataInfo.RootPath, notCheckMD5Folder), IsDirectoryTransfer = true, SourceType = DMLibTestContext.SourceType, DestType = DMLibTestContext.DestType, IsServiceCopy = DMLibTestContext.IsAsync, TransferContext = context, Options = new DownloadDirectoryOptions() { DisableContentMD5Validation = true, Recursive = true, }, CancellationToken = cancellationTokenSource.Token }; var executionOption = new TestExecutionOptions <DMLibDataInfo>(); executionOption.AfterAllItemAdded = () => { // Wait until there are data transferred progressChecker.DataTransferred.WaitOne(); // Cancel the transfer and store the second checkpoint cancellationTokenSource.Cancel(); }; executionOption.LimitSpeed = true; var testResult = this.RunTransferItems(new List <TransferItem>() { checkMD5Item, notCheckMD5Item }, executionOption); eventChecker = new TransferEventChecker(); context = new DirectoryTransferContext(DMLibTestHelper.RandomReloadCheckpoint(context.LastCheckpoint)); eventChecker.Apply(context); bool failureReported = false; context.FileFailed += (sender, args) => { if (args.Exception != null) { failureReported = args.Exception.Message.Contains(checkWrongMD5File); } transferExceptions.Add(args.Exception); }; progressChecker.Reset(); context.ProgressHandler = progressChecker.GetProgressHandler(); checkMD5Item = checkMD5Item.Clone(); notCheckMD5Item = notCheckMD5Item.Clone(); checkMD5Item.TransferContext = context; notCheckMD5Item.TransferContext = context; testResult = this.RunTransferItems(new List <TransferItem>() { checkMD5Item, notCheckMD5Item }, new TestExecutionOptions <DMLibDataInfo>()); DMLibDataInfo expectedDataInfo = sourceDataInfo.Clone(); DMLibDataInfo actualDataInfo = testResult.DataInfo; for (int i = 0; i < fileCountMulti; ++i) { expectedDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode($"{checkWrongMD5File}_{i}"); expectedDataInfo.RootNode.GetDirNode(notCheckMD5Folder.Name).DeleteFileNode($"{notCheckWrongMD5File}_{i}"); actualDataInfo.RootNode.GetDirNode(checkMD5Folder.Name).DeleteFileNode($"{checkWrongMD5File}_{i}"); actualDataInfo.RootNode.GetDirNode(notCheckMD5Folder.Name).DeleteFileNode($"{notCheckWrongMD5File}_{i}"); } Test.Assert(DMLibDataHelper.Equals(expectedDataInfo, actualDataInfo), "Verify transfer result."); Test.Assert(failureReported, "Verify md5 check failure is reported."); VerificationHelper.VerifyFinalProgress(progressChecker, 3 * fileCountMulti, 0, fileCountMulti); if (testResult.Exceptions.Count != 0 || transferExceptions.Count != fileCountMulti) { Test.Error("Expect one exception but actually no exception is thrown."); } else { for (int i = 0; i < fileCountMulti; ++i) { VerificationHelper.VerifyExceptionErrorMessage(transferExceptions[i], new string[] { "The MD5 hash calculated from the downloaded data does not match the MD5 hash stored in the property of source" }); } } }
private void TestSASTokenOfEachVersion(string targetSASVersion, bool isDirectoryTransfer) { Test.Info("Testing version of {0}", targetSASVersion); DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, DMLibTestBase.FileName, 1024); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = isDirectoryTransfer; options.TransferItemModifier = (fileNode, transferItem) => { dynamic transferOptions = isDirectoryTransfer ? DefaultTransferDirectoryOptions : DefaultTransferOptions; transferItem.Options = transferOptions; if (isDirectoryTransfer) { transferItem.TransferContext = new DirectoryTransferContext(); transferItem.TransferContext.FileFailed += (source, e) => { Test.Error(e.Exception.ToString()); }; DirectoryOptions dirOptions = transferItem.Options as DirectoryOptions; dirOptions.Recursive = true; } else { transferItem.TransferContext = new SingleTransferContext(); } transferItem.TransferContext.ShouldOverwriteCallbackAsync = TransferContext.ForceOverwrite; }; string sourceSAS = null; string destSAS = null; switch (DMLibTestContext.SourceType) { case DMLibDataType.CloudBlob: case DMLibDataType.AppendBlob: case DMLibDataType.BlockBlob: case DMLibDataType.PageBlob: if ((DMLibTestContext.SourceType == DMLibDataType.AppendBlob) && (string.CompareOrdinal(targetSASVersion, "2015-04-05") < 0)) { break; } SourceAdaptor.CreateIfNotExists(); CloudBlobDataAdaptor blobAdaptor = SourceAdaptor as CloudBlobDataAdaptor; sourceSAS = Util.SASGenerator.GetSharedAccessSignature(blobAdaptor.GetBaseContainer(), new SharedAccessBlobPolicy { Permissions = isDirectoryTransfer ? SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List : SharedAccessBlobPermissions.Read, SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(1) }, null, null, null, targetSASVersion); break; case DMLibDataType.CloudFile: if (string.CompareOrdinal(targetSASVersion, "2015-02-21") < 0) { break; } SourceAdaptor.CreateIfNotExists(); CloudFileDataAdaptor fileAdaptor = SourceAdaptor as CloudFileDataAdaptor; sourceSAS = Util.SASGenerator.GetSharedAccessSignature( fileAdaptor.GetBaseShare(), new SharedAccessFilePolicy { Permissions = isDirectoryTransfer ? SharedAccessFilePermissions.List | SharedAccessFilePermissions.Read : SharedAccessFilePermissions.Read, SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(1) }, null, null, null, targetSASVersion); break; default: break; } if (!DMLibTestContext.IsAsync || (string.CompareOrdinal(targetSASVersion, "2014-02-14") >= 0)) { switch (DMLibTestContext.DestType) { case DMLibDataType.CloudBlob: case DMLibDataType.AppendBlob: case DMLibDataType.BlockBlob: case DMLibDataType.PageBlob: if ((DMLibTestContext.DestType == DMLibDataType.AppendBlob) && (string.CompareOrdinal(targetSASVersion, "2015-04-05") < 0)) { break; } DestAdaptor.CreateIfNotExists(); CloudBlobDataAdaptor blobAdaptor = DestAdaptor as CloudBlobDataAdaptor; destSAS = Util.SASGenerator.GetSharedAccessSignature(blobAdaptor.GetBaseContainer(), new SharedAccessBlobPolicy { Permissions = DMLibTestContext.IsAsync ? SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read : SharedAccessBlobPermissions.Write, SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(1) }, null, null, null, targetSASVersion); break; case DMLibDataType.CloudFile: if (string.CompareOrdinal(targetSASVersion, "2015-02-21") < 0) { break; } DestAdaptor.CreateIfNotExists(); CloudFileDataAdaptor fileAdaptor = DestAdaptor as CloudFileDataAdaptor; destSAS = Util.SASGenerator.GetSharedAccessSignature( fileAdaptor.GetBaseShare(), new SharedAccessFilePolicy { Permissions = DMLibTestContext.IsAsync ? SharedAccessFilePermissions.Write | SharedAccessFilePermissions.Read : SharedAccessFilePermissions.Write, SharedAccessExpiryTime = DateTimeOffset.UtcNow.AddHours(1) }, null, null, null, targetSASVersion); break; default: break; } } if (null != sourceSAS) { options.SourceCredentials = new StorageCredentials(sourceSAS); } if (null != destSAS) { options.DestCredentials = new StorageCredentials(destSAS); } var result = this.ExecuteTestCase(sourceDataInfo, options); VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo); }
public void TestDirectoryWithSpecialCharNamedBlobs() { #if DNXCORE50 // TODO: There's a known issue that signature for URI with '[' or ']' doesn't work. string specialChars = "~`!@#$%()-_+={};?.^&"; #else string specialChars = "~`!@#$%()-_+={}[];?.^&"; #endif DMLibDataInfo sourceDataInfo = new DMLibDataInfo(string.Empty); var subDirWithDot = new DirNode(DMLibTestBase.FolderName + "." + DMLibTestBase.FolderName); for (int i = 0; i < specialChars.Length; ++i) { string fileName = DMLibTestBase.FileName + specialChars[i] + DMLibTestBase.FileName; if (random.Next(2) == 0) { if ((specialChars[i] != '.') && (random.Next(2) == 0)) { string folderName = DMLibTestBase.FolderName + specialChars[i] + DMLibTestBase.FolderName; var subDir = new DirNode(folderName); DMLibDataHelper.AddOneFileInBytes(subDir, fileName, 1024); FileNode fileNode1 = subDir.GetFileNode(fileName); fileNode1.SnapshotsCount = 1; sourceDataInfo.RootNode.AddDirNode(subDir); } else { DMLibDataHelper.AddOneFileInBytes(subDirWithDot, fileName, 1024); FileNode fileNode1 = subDirWithDot.GetFileNode(fileName); fileNode1.SnapshotsCount = 1; } } else { DMLibDataHelper.AddOneFileInBytes(sourceDataInfo.RootNode, fileName, 1024); FileNode fileNode1 = sourceDataInfo.RootNode.GetFileNode(fileName); fileNode1.SnapshotsCount = 1; } } sourceDataInfo.RootNode.AddDirNode(subDirWithDot); var options = new TestExecutionOptions <DMLibDataInfo>(); options.IsDirectoryTransfer = true; // transfer with IncludeSnapshots = true options.TransferItemModifier = (fileNode, transferItem) => { dynamic dirOptions = DefaultTransferDirectoryOptions; dirOptions.Recursive = true; dirOptions.IncludeSnapshots = true; transferItem.Options = dirOptions; }; var result = this.ExecuteTestCase(sourceDataInfo, options); // verify that snapshots are transferred Test.Assert(result.Exceptions.Count == 0, "Verify no exception is thrown."); Test.Assert(DMLibDataHelper.Equals(sourceDataInfo, result.DataInfo), "Verify transfer result."); }