Moved fast MoveSeriesFolder logic if same RootFolder into DiskTransferService.

This commit is contained in:
Taloth Saldono 2019-01-21 22:18:37 +01:00
parent 9107d1678c
commit b1a8c70d20
3 changed files with 138 additions and 15 deletions

View File

@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FluentAssertions;
using Moq;
using NUnit.Framework;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Test.Common;
using FluentAssertions;
namespace NzbDrone.Common.Test.DiskTests
{
@ -794,6 +796,57 @@ namespace NzbDrone.Common.Test.DiskTests
VerifyCopyFolder(original.FullName, destination.FullName);
}
[Test]
public void TransferFolder_should_use_movefolder_if_on_same_mount()
{
WithEmulatedDiskProvider();
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
var dst = @"C:\Base1\TestDir2".AsOsAgnostic();
WithMockMount(@"C:\Base1".AsOsAgnostic());
WithExistingFile(@"C:\Base1\TestDir1\test.file.txt".AsOsAgnostic());
Subject.TransferFolder(src, dst, TransferMode.Move);
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.MoveFolder(src, dst), Times.Once());
}
[Test]
public void TransferFolder_should_not_use_movefolder_if_on_same_mount_but_transactional()
{
WithEmulatedDiskProvider();
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
var dst = @"C:\Base1\TestDir2".AsOsAgnostic();
WithMockMount(@"C:\Base1".AsOsAgnostic());
WithExistingFile(@"C:\Base1\TestDir1\test.file.txt".AsOsAgnostic());
Subject.TransferFolder(src, dst, TransferMode.Move, DiskTransferVerificationMode.Transactional);
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.MoveFolder(src, dst), Times.Never());
}
[Test]
public void TransferFolder_should_not_use_movefolder_if_on_different_mount()
{
WithEmulatedDiskProvider();
var src = @"C:\Base1\TestDir1".AsOsAgnostic();
var dst = @"C:\Base2\TestDir2".AsOsAgnostic();
WithMockMount(@"C:\Base1".AsOsAgnostic());
WithMockMount(@"C:\Base2".AsOsAgnostic());
Subject.TransferFolder(src, dst, TransferMode.Move);
Mocker.GetMock<IDiskProvider>()
.Verify(v => v.MoveFolder(src, dst), Times.Never());
}
public DirectoryInfo GetFilledTempFolder()
{
var tempFolder = GetTempFilePath();
@ -810,8 +863,23 @@ namespace NzbDrone.Common.Test.DiskTests
return new DirectoryInfo(tempFolder);
}
private void WithExistingFolder(string path, bool exists = true)
{
var dir = Path.GetDirectoryName(path);
if (exists && dir.IsNotNullOrWhiteSpace())
WithExistingFolder(dir);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FolderExists(path))
.Returns(exists);
}
private void WithExistingFile(string path, bool exists = true, int size = 1000)
{
var dir = Path.GetDirectoryName(path);
if (exists && dir.IsNotNullOrWhiteSpace())
WithExistingFolder(dir);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(path))
.Returns(exists);
@ -863,6 +931,45 @@ namespace NzbDrone.Common.Test.DiskTests
{
WithExistingFile(v, false);
});
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FolderExists(It.IsAny<string>()))
.Returns(false);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.CreateFolder(It.IsAny<string>()))
.Callback<string>((f) =>
{
WithExistingFolder(f);
});
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.MoveFolder(It.IsAny<string>(), It.IsAny<string>()))
.Callback<string, string>((s, d) =>
{
WithExistingFolder(s, false);
WithExistingFolder(d);
// Note: Should also deal with the files.
});
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.DeleteFolder(It.IsAny<string>(), It.IsAny<bool>()))
.Callback<string, bool>((f, r) =>
{
WithExistingFolder(f, false);
// Note: Should also deal with the files.
});
// Note: never returns anything.
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetDirectoryInfos(It.IsAny<string>()))
.Returns(new List<DirectoryInfo>());
// Note: never returns anything.
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetFileInfos(It.IsAny<string>()))
.Returns(new List<FileInfo>());
}
private void WithRealDiskProvider()
@ -919,6 +1026,18 @@ namespace NzbDrone.Common.Test.DiskTests
.Returns<string>(s => new FileStream(s, FileMode.Open, FileAccess.Read));
}
private void WithMockMount(string root)
{
var rootDir = root;
var mock = new Mock<IMount>();
mock.SetupGet(v => v.RootDirectory)
.Returns(rootDir);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.GetMount(It.Is<string>(s => s.StartsWith(rootDir))))
.Returns(mock.Object);
}
private void VerifyCopyFolder(string source, string destination)
{
var sourceFiles = Directory.GetFileSystemEntries(source, "*", SearchOption.AllDirectories).Select(v => v.Substring(source.Length + 1)).ToArray();

View File

@ -56,6 +56,23 @@ namespace NzbDrone.Common.Disk
Ensure.That(sourcePath, () => sourcePath).IsValidPath();
Ensure.That(targetPath, () => targetPath).IsValidPath();
if (mode == TransferMode.Move)
{
if (verificationMode == DiskTransferVerificationMode.TryTransactional || verificationMode == DiskTransferVerificationMode.VerifyOnly)
{
var sourceMount = _diskProvider.GetMount(sourcePath);
var targetMount = _diskProvider.GetMount(targetPath);
// If we're on the same mount, do a simple folder move.
if (sourceMount != null && targetMount != null && sourceMount.RootDirectory == targetMount.RootDirectory)
{
_logger.Debug("Move Directory [{0}] > [{1}]", sourcePath, targetPath);
_diskProvider.MoveFolder(sourcePath, targetPath);
return mode;
}
}
}
if (!_diskProvider.FolderExists(targetPath))
{
_diskProvider.CreateFolder(targetPath);

View File

@ -1,7 +1,6 @@
using System.IO;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation.Extensions;
using NzbDrone.Core.Messaging.Commands;
using NzbDrone.Core.Messaging.Events;
@ -26,7 +25,6 @@ namespace NzbDrone.Core.Tv
IBuildFileNames filenameBuilder,
IDiskProvider diskProvider,
IDiskTransferService diskTransferService,
IRootFolderService rootFolderService,
IEventAggregator eventAggregator,
Logger logger)
{
@ -34,7 +32,6 @@ namespace NzbDrone.Core.Tv
_filenameBuilder = filenameBuilder;
_diskProvider = diskProvider;
_diskTransferService = diskTransferService;
_rootFolderService = rootFolderService;
_eventAggregator = eventAggregator;
_logger = logger;
}
@ -58,17 +55,7 @@ namespace NzbDrone.Core.Tv
try
{
var sourceRootFolder = _rootFolderService.GetBestRootFolderPath(sourcePath);
var destinationRootFolder = _rootFolderService.GetBestRootFolderPath(destinationPath);
if (sourceRootFolder.PathEquals(destinationRootFolder) && !_diskProvider.FolderExists(destinationPath))
{
_diskProvider.MoveFolder(sourcePath, destinationPath);
}
else
{
_diskTransferService.TransferFolder(sourcePath, destinationPath, TransferMode.Move);
}
_diskTransferService.TransferFolder(sourcePath, destinationPath, TransferMode.Move);
_logger.ProgressInfo("{0} moved successfully to {1}", series.Title, series.Path);