예제 #1
0
        public void TestDirectoryResume()
        {
            int  bigFileSizeInKB   = 5 * 1024; // 5 MB
            int  smallFileSizeInKB = 1;        // 1 KB
            int  bigFileNum        = 5;
            int  smallFileNum      = 50;
            long totalSizeInBytes  = (bigFileSizeInKB * bigFileNum + smallFileSizeInKB * smallFileNum) * 1024;
            int  totalFileNum      = bigFileNum + smallFileNum;

            DMLibDataInfo sourceDataInfo   = new DMLibDataInfo(string.Empty);
            DirNode       bigFileDirNode   = new DirNode("big");
            DirNode       smallFileDirNode = new DirNode("small");

            sourceDataInfo.RootNode.AddDirNode(bigFileDirNode);
            sourceDataInfo.RootNode.AddDirNode(smallFileDirNode);

            DMLibDataHelper.AddMultipleFiles(bigFileDirNode, FileName, bigFileNum, bigFileSizeInKB);
            DMLibDataHelper.AddMultipleFiles(smallFileDirNode, FileName, smallFileNum, smallFileSizeInKB);

            CancellationTokenSource tokenSource = new CancellationTokenSource();

            TransferItem transferItem = null;
            var          options      = new TestExecutionOptions <DMLibDataInfo>();

            options.LimitSpeed          = true;
            options.IsDirectoryTransfer = true;

            var transferContext = new TransferContext();
            var progressChecker = new ProgressChecker(totalFileNum, totalSizeInBytes, totalFileNum, null, 0, totalSizeInBytes);

            transferContext.ProgressHandler = progressChecker.GetProgressHandler();
            var eventChecker = new TransferEventChecker();

            eventChecker.Apply(transferContext);

            transferContext.FileFailed += (sender, e) =>
            {
                Test.Assert(e.Exception.Message.Contains("cancel"), "Verify task is canceled: {0}", e.Exception.Message);
            };

            options.TransferItemModifier = (fileName, item) =>
            {
                dynamic dirOptions = DefaultTransferDirectoryOptions;
                dirOptions.Recursive = true;

                item.Options           = dirOptions;
                item.CancellationToken = tokenSource.Token;
                item.TransferContext   = transferContext;
                transferItem           = item;
            };

            TransferCheckpoint firstCheckpoint = null, secondCheckpoint = null;

            options.AfterAllItemAdded = () =>
            {
                // Wait until there are data transferred
                progressChecker.DataTransferred.WaitOne();

                // Store the first checkpoint
                firstCheckpoint = transferContext.LastCheckpoint;
                Thread.Sleep(100);

                // Cancel the transfer and store the second checkpoint
                tokenSource.Cancel();
            };

            // Cancel and store checkpoint for resume
            var result = this.ExecuteTestCase(sourceDataInfo, options);

            secondCheckpoint = transferContext.LastCheckpoint;

            if (progressChecker.FailedFilesNumber <= 0)
            {
                Test.Error("Verify file number in progress. Failed: {0}", progressChecker.FailedFilesNumber);
            }

            TransferCheckpoint firstResumeCheckpoint = null, secondResumeCheckpoint = null;

            Test.Info("Resume with the second checkpoint first.");
            firstResumeCheckpoint  = secondCheckpoint;
            secondResumeCheckpoint = firstCheckpoint;

            // resume with firstResumeCheckpoint
            TransferItem resumeItem = transferItem.Clone();

            progressChecker.Reset();
            TransferContext resumeContext = new TransferContext(DMLibTestHelper.RandomReloadCheckpoint(firstResumeCheckpoint))
            {
                ProgressHandler = progressChecker.GetProgressHandler()
            };

            eventChecker.Reset();
            eventChecker.Apply(resumeContext);

            resumeItem.TransferContext = resumeContext;

            result = this.RunTransferItems(new List <TransferItem>()
            {
                resumeItem
            }, new TestExecutionOptions <DMLibDataInfo>());

            VerificationHelper.VerifyFinalProgress(progressChecker, totalFileNum, 0, 0);
            VerificationHelper.VerifySingleTransferStatus(result, totalFileNum, 0, 0, totalSizeInBytes);
            VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo);

            // resume with secondResumeCheckpoint
            resumeItem = transferItem.Clone();

            progressChecker.Reset();
            resumeContext = new TransferContext(DMLibTestHelper.RandomReloadCheckpoint(secondResumeCheckpoint))
            {
                ProgressHandler = progressChecker.GetProgressHandler(),

                // Need this overwrite callback since some files is already transferred to destination
                OverwriteCallback = DMLibInputHelper.GetDefaultOverwiteCallbackY(),
            };

            eventChecker.Reset();
            eventChecker.Apply(resumeContext);

            resumeItem.TransferContext = resumeContext;

            result = this.RunTransferItems(new List <TransferItem>()
            {
                resumeItem
            }, new TestExecutionOptions <DMLibDataInfo>());

            VerificationHelper.VerifyFinalProgress(progressChecker, totalFileNum, 0, 0);
            VerificationHelper.VerifySingleTransferStatus(result, totalFileNum, 0, 0, totalSizeInBytes);
            VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo);
        }
예제 #2
0
        public void TestDirectoryResume()
        {
            int  bigFileSizeInKB   = 5 * 1024; // 5 MB
            int  smallFileSizeInKB = 1;        // 1 KB
            int  bigFileNum        = 5;
            int  smallFileNum      = 50;
            long totalSizeInBytes  = (bigFileSizeInKB * bigFileNum + smallFileSizeInKB * smallFileNum) * 1024;
            int  totalFileNum      = bigFileNum + smallFileNum;

            DMLibDataInfo sourceDataInfo   = new DMLibDataInfo(string.Empty);
            DirNode       bigFileDirNode   = new DirNode("big");
            DirNode       smallFileDirNode = new DirNode("small");

            sourceDataInfo.RootNode.AddDirNode(bigFileDirNode);
            sourceDataInfo.RootNode.AddDirNode(smallFileDirNode);

            DMLibDataHelper.AddMultipleFiles(bigFileDirNode, FileName, bigFileNum, bigFileSizeInKB);
            DMLibDataHelper.AddMultipleFiles(smallFileDirNode, FileName, smallFileNum, smallFileSizeInKB);

            CancellationTokenSource tokenSource = new CancellationTokenSource();

            TransferItem transferItem = null;
            var          options      = new TestExecutionOptions <DMLibDataInfo>();

            options.LimitSpeed          = true;
            options.IsDirectoryTransfer = true;

            using (Stream journalStream = new MemoryStream())
            {
                bool IsStreamJournal = random.Next(0, 2) == 0;
                var  transferContext = IsStreamJournal ? new DirectoryTransferContext(journalStream) : new DirectoryTransferContext();
                var  progressChecker = new ProgressChecker(totalFileNum, totalSizeInBytes, totalFileNum, null, 0, totalSizeInBytes);
                transferContext.ProgressHandler = progressChecker.GetProgressHandler();
                var eventChecker = new TransferEventChecker();
                eventChecker.Apply(transferContext);

                transferContext.FileFailed += (sender, e) =>
                {
                    Helper.VerifyCancelException(e.Exception);
                };

                options.TransferItemModifier = (fileName, item) =>
                {
                    dynamic dirOptions = DefaultTransferDirectoryOptions;
                    dirOptions.Recursive = true;

                    if (DMLibTestContext.SourceType == DMLibDataType.CloudFile &&
                        DMLibTestContext.DestType == DMLibDataType.CloudFile)
                    {
                        dirOptions.PreserveSMBAttributes  = true;
                        dirOptions.PreserveSMBPermissions = true;
                    }

                    item.Options           = dirOptions;
                    item.CancellationToken = tokenSource.Token;
                    item.TransferContext   = transferContext;
                    transferItem           = item;
                };

                TransferCheckpoint firstCheckpoint = null, secondCheckpoint = null;
                options.AfterAllItemAdded = () =>
                {
                    // Wait until there are data transferred
                    progressChecker.DataTransferred.WaitOne();

                    if (!IsStreamJournal)
                    {
                        // Store the first checkpoint
                        firstCheckpoint = transferContext.LastCheckpoint;
                    }

                    Thread.Sleep(1000);

                    // Cancel the transfer and store the second checkpoint
                    tokenSource.Cancel();
                };

                // Cancel and store checkpoint for resume
                var result = this.ExecuteTestCase(sourceDataInfo, options);

                if (progressChecker.FailedFilesNumber <= 0)
                {
                    Test.Error("Verify file number in progress. Failed: {0}", progressChecker.FailedFilesNumber);
                }

                TransferCheckpoint firstResumeCheckpoint = null, secondResumeCheckpoint = null;

                if (!IsStreamJournal)
                {
                    secondCheckpoint = transferContext.LastCheckpoint;

                    Test.Info("Resume with the second checkpoint first.");
                    firstResumeCheckpoint  = secondCheckpoint;
                    secondResumeCheckpoint = firstCheckpoint;
                }

                // resume with firstResumeCheckpoint
                TransferItem resumeItem = transferItem.Clone();

                progressChecker.Reset();
                TransferContext resumeContext = null;

                if (IsStreamJournal)
                {
                    resumeContext = new DirectoryTransferContext(journalStream)
                    {
                        ProgressHandler = progressChecker.GetProgressHandler()
                    };
                }
                else
                {
                    resumeContext = new DirectoryTransferContext(DMLibTestHelper.RandomReloadCheckpoint(firstResumeCheckpoint))
                    {
                        ProgressHandler = progressChecker.GetProgressHandler()
                    };
                }

                eventChecker.Reset();
                eventChecker.Apply(resumeContext);

                resumeItem.TransferContext = resumeContext;

                result = this.RunTransferItems(new List <TransferItem>()
                {
                    resumeItem
                }, new TestExecutionOptions <DMLibDataInfo>());

                VerificationHelper.VerifyFinalProgress(progressChecker, totalFileNum, 0, 0);
                VerificationHelper.VerifySingleTransferStatus(result, totalFileNum, 0, 0, totalSizeInBytes);
                VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo);

                if (!IsStreamJournal)
                {
                    // resume with secondResumeCheckpoint
                    resumeItem = transferItem.Clone();

                    progressChecker.Reset();
                    resumeContext = new DirectoryTransferContext(DMLibTestHelper.RandomReloadCheckpoint(secondResumeCheckpoint))
                    {
                        ProgressHandler = progressChecker.GetProgressHandler(),

                        // Need this overwrite callback since some files is already transferred to destination
                        ShouldOverwriteCallbackAsync = DMLibInputHelper.GetDefaultOverwiteCallbackY(),
                    };

                    eventChecker.Reset();
                    eventChecker.Apply(resumeContext);

                    resumeItem.TransferContext = resumeContext;

                    result = this.RunTransferItems(new List <TransferItem>()
                    {
                        resumeItem
                    }, new TestExecutionOptions <DMLibDataInfo>());

                    VerificationHelper.VerifyFinalProgress(progressChecker, totalFileNum, 0, 0);
                    VerificationHelper.VerifySingleTransferStatus(result, totalFileNum, 0, 0, totalSizeInBytes);
                    VerificationHelper.VerifyTransferSucceed(result, sourceDataInfo);
                }

                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);
                }
            }
        }