diff --git a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs index 68b051838..053138307 100644 --- a/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs +++ b/NzbDrone.Core.Test/ProviderTests/PostDownloadProviderTests/ProcessDownloadProviderFixture.cs @@ -25,7 +25,9 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests [SetUp] public void Setup() { - fakeSeries = Builder.CreateNew().Build(); + fakeSeries = Builder.CreateNew() + .With(s => s.Path = @"C:\Test\TV\30 Rock") + .Build(); } private void WithOldWrite() @@ -56,6 +58,21 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests .Returns(Builder.CreateListOfSize(1).Build().ToList()); } + private void WithLotsOfFreeDiskSpace() + { + Mocker.GetMock().Setup(s => s.FreeDiskSpace(It.IsAny())).Returns(1000000); + } + + private void WithImportedFiles(string droppedFolder) + { + var fakeEpisodeFiles = Builder.CreateListOfSize(2) + .All() + .With(f => f.SeriesId = fakeSeries.SeriesId) + .Build().ToList(); + + Mocker.GetMock().Setup(s => s.Scan(fakeSeries, droppedFolder)).Returns(fakeEpisodeFiles); + } + [Test] public void should_skip_if_folder_is_tagged_and_too_fresh() { @@ -267,8 +284,12 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests { //Setup WithStrictMocker(); + WithLotsOfFreeDiskSpace(); + var droppedFolder = new DirectoryInfo(@"C:\Test\Unsorted TV\The Office - Season 01"); + WithImportedFiles(droppedFolder.FullName); + var fakeSeries = Builder.CreateNew() .With(s => s.Title = "The Office") .Build(); @@ -280,7 +301,6 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests Mocker.GetMock().Setup(s => s.FindSeries("office")).Returns(fakeSeries); Mocker.GetMock().Setup(s => s.CleanUpDropFolder(droppedFolder.FullName)); - Mocker.GetMock().Setup(s => s.Scan(fakeSeries, droppedFolder.FullName)).Returns(fakeEpisodeFiles); Mocker.GetMock().Setup(s => s.MoveEpisodeFile(It.IsAny(), true)).Returns(new EpisodeFile()); Mocker.GetMock().Setup(s => s.GetDirectorySize(droppedFolder.FullName)).Returns(Constants.IgnoreFileSize - 1.Megabytes()); Mocker.GetMock().Setup(s => s.DeleteFolder(droppedFolder.FullName, true)); @@ -316,10 +336,11 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests Mocker.VerifyAllMocks(); } - [Test] public void ProcessDropFolder_should_only_process_folders_that_arent_known_series_folders() { + WithLotsOfFreeDiskSpace(); + var subFolders = new[] { @"c:\drop\episode1", @@ -338,12 +359,16 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests Mocker.GetMock() .Setup(c => c.FindSeries(It.IsAny())) - .Returns(new Series()); + .Returns(fakeSeries); Mocker.GetMock() .Setup(c => c.Scan(It.IsAny(), It.IsAny())) .Returns(new List()); + Mocker.GetMock() + .Setup(c => c.GetDirectorySize(It.IsAny())) + .Returns(10); + //Act Mocker.Resolve().ProcessDropFolder(@"C:\drop\"); @@ -354,5 +379,86 @@ namespace NzbDrone.Core.Test.ProviderTests.PostDownloadProviderTests Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[2]), Times.Once()); Mocker.GetMock().Verify(c => c.Scan(It.IsAny(), subFolders[3]), Times.Once()); } + + [Test] + public void ProcessDownload_should_logError_and_return_if_size_exceeds_free_space() + { + var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot"); + + var series = Builder.CreateNew() + .With(s => s.Title = "30 Rock") + .With(s => s.Path = @"C:\Test\TV\30 Rock") + .Build(); + + Mocker.GetMock() + .Setup(c => c.FindSeries("rock")) + .Returns(series); + + Mocker.GetMock() + .Setup(s => s.GetDirectorySize(downloadName.FullName)) + .Returns(10); + + Mocker.GetMock() + .Setup(s => s.FreeDiskSpace(new DirectoryInfo(series.Path))) + .Returns(9); + + //Act + Mocker.Resolve().ProcessDownload(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.Scan(series, downloadName.FullName), Times.Never()); + ExceptionVerification.ExpectedErrors(1); + } + + [Test] + public void ProcessDownload_should_process_if_free_disk_space_exceeds_size() + { + WithLotsOfFreeDiskSpace(); + WithValidSeries(); + + var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot"); + + WithImportedFiles(downloadName.FullName); + + Mocker.GetMock() + .Setup(c => c.FindSeries("rock")) + .Returns(fakeSeries); + + Mocker.GetMock() + .Setup(s => s.GetDirectorySize(downloadName.FullName)) + .Returns(8); + + //Act + Mocker.Resolve().ProcessDownload(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once()); + } + + [Test] + public void ProcessDownload_should_process_if_free_disk_space_equals_size() + { + var downloadName = new DirectoryInfo(@"C:\Test\Drop\30.Rock.S01E01.Pilot"); + + WithImportedFiles(downloadName.FullName); + WithValidSeries(); + + Mocker.GetMock() + .Setup(s => s.GetDirectorySize(downloadName.FullName)) + .Returns(10); + + Mocker.GetMock() + .Setup(s => s.FreeDiskSpace(It.IsAny())) + .Returns(10); + + //Act + Mocker.Resolve().ProcessDownload(downloadName); + + + //Assert + Mocker.GetMock().Verify(c => c.Scan(fakeSeries, downloadName.FullName), Times.Once()); + } } } \ No newline at end of file diff --git a/NzbDrone.Core/Providers/PostDownloadProvider.cs b/NzbDrone.Core/Providers/PostDownloadProvider.cs index 244a202b3..1148cfdcf 100644 --- a/NzbDrone.Core/Providers/PostDownloadProvider.cs +++ b/NzbDrone.Core/Providers/PostDownloadProvider.cs @@ -68,6 +68,15 @@ namespace NzbDrone.Core.Providers return; } + var size = _diskProvider.GetDirectorySize(subfolderInfo.FullName); + var freeSpace = _diskProvider.FreeDiskSpace(new DirectoryInfo(series.Path)); + + if (Convert.ToUInt64(size) > freeSpace) + { + Logger.Error("Not enough free disk space for series: {0}, {1}", series.Title, series.Path); + return; + } + _diskScanProvider.CleanUpDropFolder(subfolderInfo.FullName); var importedFiles = _diskScanProvider.Scan(series, subfolderInfo.FullName);