using System; using System.Collections.Generic; using System.Linq; using Moq; using NzbDrone.Core.Indexers; using NzbDrone.Core.Profiles.Delay; using NzbDrone.Core.Tv; using NzbDrone.Core.Profiles; using NzbDrone.Core.Qualities; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.DecisionEngine; using NUnit.Framework; using FluentAssertions; using FizzWare.NBuilder; using NzbDrone.Common.Extensions; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.DecisionEngineTests { [TestFixture] public class PrioritizeDownloadDecisionFixture : CoreTest { [SetUp] public void Setup() { GivenPreferredDownloadProtocol(DownloadProtocol.Usenet); } private RemoteMovie GivenRemoteMovie(QualityModel quality, int age = 0, long size = 0, DownloadProtocol downloadProtocol = DownloadProtocol.Usenet) { var remoteMovie = new RemoteMovie(); remoteMovie.ParsedMovieInfo = new ParsedMovieInfo(); remoteMovie.ParsedMovieInfo.MovieTitle = "A Movie"; remoteMovie.ParsedMovieInfo.Year = 1998; remoteMovie.ParsedMovieInfo.MovieTitleInfo = new SeriesTitleInfo { Year = 1998}; remoteMovie.ParsedMovieInfo.MovieTitleInfo.Year = 1998; remoteMovie.ParsedMovieInfo.Quality = quality; remoteMovie.Movie = Builder.CreateNew().With(m => m.Profile = new Profile { Items = Qualities.QualityFixture.GetDefaultQualities(), PreferredTags = new List { "DTS-HD", "SPARKS"} }) .With(m => m.Title = "A Movie").Build(); remoteMovie.Release = new ReleaseInfo(); remoteMovie.Release.PublishDate = DateTime.Now.AddDays(-age); remoteMovie.Release.Size = size; remoteMovie.Release.DownloadProtocol = downloadProtocol; remoteMovie.Release.Title = "A Movie 1998"; return remoteMovie; } private void GivenPreferredDownloadProtocol(DownloadProtocol downloadProtocol) { Mocker.GetMock() .Setup(s => s.BestForTags(It.IsAny>())) .Returns(new DelayProfile { PreferredProtocol = downloadProtocol }); } [Test] public void should_put_propers_before_non_propers() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 1))); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p, new Revision(version: 2))); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Revision.Version.Should().Be(2); } [Test] public void should_put_higher_quality_before_lower() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.SDTV)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.ParsedMovieInfo.Quality.Quality.Should().Be(Quality.HDTV720p); } [Test] public void should_order_by_age_then_largest_rounded_to_200mb() { var remoteEpisodeSd = GivenRemoteMovie(new QualityModel(Quality.SDTV), size: 100.Megabytes(), age: 1); var remoteEpisodeHdSmallOld = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1200.Megabytes(), age: 1000); var remoteEpisodeSmallYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 1250.Megabytes(), age: 10); var remoteEpisodeHdLargeYoung = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), size: 3000.Megabytes(), age: 1); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisodeSd)); decisions.Add(new DownloadDecision(remoteEpisodeHdSmallOld)); decisions.Add(new DownloadDecision(remoteEpisodeSmallYoung)); decisions.Add(new DownloadDecision(remoteEpisodeHdLargeYoung)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisodeHdLargeYoung); } [Test] public void should_order_by_youngest() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 10); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), age: 5); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Should().Be(remoteEpisode2); } [Test] public void should_put_usenet_above_torrent_when_usenet_is_preferred() { GivenPreferredDownloadProtocol(DownloadProtocol.Usenet); var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Usenet); } [Test] public void should_put_torrent_above_usenet_when_torrent_is_preferred() { GivenPreferredDownloadProtocol(DownloadProtocol.Torrent); var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Torrent); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p), downloadProtocol: DownloadProtocol.Usenet); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Release.DownloadProtocol.Should().Be(DownloadProtocol.Torrent); } [Test] public void should_prefer_releases_with_more_seeders() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var torrentInfo1 = new TorrentInfo(); torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.Size = 0; torrentInfo1.DownloadProtocol = DownloadProtocol.Torrent; torrentInfo1.Seeders = 10; var torrentInfo2 = torrentInfo1.JsonClone(); torrentInfo2.Seeders = 100; remoteEpisode1.Release = torrentInfo1; remoteEpisode1.Release.Title = "A Movie 1998"; remoteEpisode2.Release = torrentInfo2; remoteEpisode2.Release.Title = "A Movie 1998"; var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); ((TorrentInfo) qualifiedReports.First().RemoteMovie.Release).Seeders.Should().Be(torrentInfo2.Seeders); } [Test] public void should_prefer_releases_with_more_peers_given_equal_number_of_seeds() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var torrentInfo1 = new TorrentInfo(); torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.Size = 0; torrentInfo1.DownloadProtocol = DownloadProtocol.Torrent; torrentInfo1.Seeders = 10; torrentInfo1.Peers = 10; var torrentInfo2 = torrentInfo1.JsonClone(); torrentInfo2.Peers = 100; remoteEpisode1.Release = torrentInfo1; remoteEpisode1.Release.Title = "A Movie 1998"; remoteEpisode2.Release = torrentInfo2; remoteEpisode2.Release.Title = "A Movie 1998"; var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); ((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers); } [Test] public void should_prefer_releases_with_more_peers_no_seeds() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var torrentInfo1 = new TorrentInfo(); torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.Size = 0; torrentInfo1.DownloadProtocol = DownloadProtocol.Torrent; torrentInfo1.Seeders = 0; torrentInfo1.Peers = 10; var torrentInfo2 = torrentInfo1.JsonClone(); torrentInfo2.Seeders = 0; torrentInfo2.Peers = 100; remoteEpisode1.Release = torrentInfo1; remoteEpisode1.Release.Title = "A Movie 1998"; remoteEpisode2.Release = torrentInfo2; remoteEpisode2.Release.Title = "A Movie 1998"; var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); ((TorrentInfo)qualifiedReports.First().RemoteMovie.Release).Peers.Should().Be(torrentInfo2.Peers); } [Test] public void should_prefer_first_release_if_peers_and_size_are_too_similar() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var torrentInfo1 = new TorrentInfo(); torrentInfo1.PublishDate = DateTime.Now; torrentInfo1.DownloadProtocol = DownloadProtocol.Torrent; torrentInfo1.Seeders = 1000; torrentInfo1.Peers = 10; torrentInfo1.Size = 200.Megabytes(); var torrentInfo2 = torrentInfo1.JsonClone(); torrentInfo2.Seeders = 1100; torrentInfo2.Peers = 10; torrentInfo1.Size = 250.Megabytes(); remoteEpisode1.Release = torrentInfo1; remoteEpisode1.Release.Title = "A Movie 1998"; remoteEpisode2.Release = torrentInfo2; remoteEpisode2.Release.Title = "A Movie 1998"; var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); ((TorrentInfo) qualifiedReports.First().RemoteMovie.Release).Should().Be(torrentInfo1); } [Test] public void should_prefer_first_release_if_age_and_size_are_too_similar() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); remoteEpisode1.Release.PublishDate = DateTime.UtcNow.AddDays(-100); remoteEpisode1.Release.Size = 200.Megabytes(); remoteEpisode2.Release.PublishDate = DateTime.UtcNow.AddDays(-150); remoteEpisode2.Release.Size = 250.Megabytes(); var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode1.Release); } [Test] public void should_prefer_more_prioritized_words() { var remoteEpisode1 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); var remoteEpisode2 = GivenRemoteMovie(new QualityModel(Quality.HDTV720p)); remoteEpisode1.Release.Title += " DTS-HD"; remoteEpisode2.Release.Title += " DTS-HD SPARKS"; var decisions = new List(); decisions.Add(new DownloadDecision(remoteEpisode1)); decisions.Add(new DownloadDecision(remoteEpisode2)); var qualifiedReports = Subject.PrioritizeDecisionsForMovies(decisions); qualifiedReports.First().RemoteMovie.Release.Should().Be(remoteEpisode2.Release); } } }