From 2abaef16f1d3fee9cb68060637a21b78b39a9d01 Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Tue, 28 Feb 2017 20:59:22 +0100 Subject: [PATCH] Fixed Indexer Health Checks and tests. --- ...ase64Extentions.cs => Base64Extensions.cs} | 4 +- .../{XmlExtentions.cs => XmlExtensions.cs} | 4 +- src/NzbDrone.Common/NzbDrone.Common.csproj | 4 +- ...ons.cs => HealthCheckFixtureExtensions.cs} | 15 ++- .../Checks/IndexerRssCheckFixture.cs | 92 +++++++++++++++++++ ...ixture.cs => IndexerSearchCheckFixture.cs} | 81 +++++----------- .../NzbDrone.Core.Test.csproj | 5 +- .../HealthCheck/Checks/IndexerCheck.cs | 60 ------------ .../HealthCheck/Checks/IndexerRssCheck.cs | 35 +++++++ .../HealthCheck/Checks/IndexerSearchCheck.cs | 35 +++++++ .../Indexers/XElementExtensions.cs | 2 +- src/NzbDrone.Core/NzbDrone.Core.csproj | 3 +- 12 files changed, 212 insertions(+), 128 deletions(-) rename src/NzbDrone.Common/Extensions/{Base64Extentions.cs => Base64Extensions.cs} (88%) rename src/NzbDrone.Common/Extensions/{XmlExtentions.cs => XmlExtensions.cs} (91%) rename src/NzbDrone.Core.Test/HealthCheck/Checks/{HealthCheckFixtureExtentions.cs => HealthCheckFixtureExtensions.cs} (61%) create mode 100644 src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerRssCheckFixture.cs rename src/NzbDrone.Core.Test/HealthCheck/Checks/{IndexerCheckFixture.cs => IndexerSearchCheckFixture.cs} (50%) delete mode 100644 src/NzbDrone.Core/HealthCheck/Checks/IndexerCheck.cs create mode 100644 src/NzbDrone.Core/HealthCheck/Checks/IndexerRssCheck.cs create mode 100644 src/NzbDrone.Core/HealthCheck/Checks/IndexerSearchCheck.cs diff --git a/src/NzbDrone.Common/Extensions/Base64Extentions.cs b/src/NzbDrone.Common/Extensions/Base64Extensions.cs similarity index 88% rename from src/NzbDrone.Common/Extensions/Base64Extentions.cs rename to src/NzbDrone.Common/Extensions/Base64Extensions.cs index 3a2dbcf3f..1d65ac298 100644 --- a/src/NzbDrone.Common/Extensions/Base64Extentions.cs +++ b/src/NzbDrone.Common/Extensions/Base64Extensions.cs @@ -2,7 +2,7 @@ using System; namespace NzbDrone.Common.Extensions { - public static class Base64Extentions + public static class Base64Extensions { public static string ToBase64(this byte[] bytes) { @@ -14,4 +14,4 @@ namespace NzbDrone.Common.Extensions return BitConverter.GetBytes(input).ToBase64(); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Common/Extensions/XmlExtentions.cs b/src/NzbDrone.Common/Extensions/XmlExtensions.cs similarity index 91% rename from src/NzbDrone.Common/Extensions/XmlExtentions.cs rename to src/NzbDrone.Common/Extensions/XmlExtensions.cs index 5e9ffd6db..84b163165 100644 --- a/src/NzbDrone.Common/Extensions/XmlExtentions.cs +++ b/src/NzbDrone.Common/Extensions/XmlExtensions.cs @@ -5,11 +5,11 @@ using System.Xml.Linq; namespace NzbDrone.Common.Extensions { - public static class XmlExtentions + public static class XmlExtensions { public static IEnumerable FindDecendants(this XContainer container, string localName) { return container.Descendants().Where(c => c.Name.LocalName.Equals(localName, StringComparison.InvariantCultureIgnoreCase)); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Common/NzbDrone.Common.csproj b/src/NzbDrone.Common/NzbDrone.Common.csproj index 4346a2610..e36c74e15 100644 --- a/src/NzbDrone.Common/NzbDrone.Common.csproj +++ b/src/NzbDrone.Common/NzbDrone.Common.csproj @@ -135,14 +135,14 @@ - + - + diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtentions.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtensions.cs similarity index 61% rename from src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtentions.cs rename to src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtensions.cs index fa1577974..5654fa388 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtentions.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/HealthCheckFixtureExtensions.cs @@ -1,4 +1,5 @@ using FluentAssertions; +using NzbDrone.Common.Extensions; using NzbDrone.Core.HealthCheck; namespace NzbDrone.Core.Test.HealthCheck.Checks @@ -10,14 +11,24 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks result.Type.Should().Be(HealthCheckResult.Ok); } - public static void ShouldBeWarning(this Core.HealthCheck.HealthCheck result) + public static void ShouldBeWarning(this Core.HealthCheck.HealthCheck result, string message = null) { result.Type.Should().Be(HealthCheckResult.Warning); + + if (message.IsNotNullOrWhiteSpace()) + { + result.Message.Should().Contain(message); + } } - public static void ShouldBeError(this Core.HealthCheck.HealthCheck result) + public static void ShouldBeError(this Core.HealthCheck.HealthCheck result, string message = null) { result.Type.Should().Be(HealthCheckResult.Error); + + if (message.IsNotNullOrWhiteSpace()) + { + result.Message.Should().Contain(message); + } } } } diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerRssCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerRssCheckFixture.cs new file mode 100644 index 000000000..28d314005 --- /dev/null +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerRssCheckFixture.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using Moq; +using NUnit.Framework; +using NzbDrone.Core.HealthCheck.Checks; +using NzbDrone.Core.Indexers; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.HealthCheck.Checks +{ + [TestFixture] + public class IndexerRssCheckFixture : CoreTest + { + private Mock _indexerMock; + + [SetUp] + public void SetUp() + { + Mocker.GetMock() + .Setup(s => s.GetAvailableProviders()) + .Returns(new List()); + + Mocker.GetMock() + .Setup(s => s.RssEnabled(It.IsAny())) + .Returns(new List()); + } + + private void GivenIndexer(bool supportsRss, bool supportsSearch) + { + _indexerMock = Mocker.GetMock(); + _indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss); + _indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch); + + Mocker.GetMock() + .Setup(s => s.GetAvailableProviders()) + .Returns(new List { _indexerMock.Object }); + } + + private void GivenRssEnabled() + { + Mocker.GetMock() + .Setup(s => s.RssEnabled(It.IsAny())) + .Returns(new List { _indexerMock.Object }); + } + + private void GivenRssFiltered() + { + Mocker.GetMock() + .Setup(s => s.RssEnabled(false)) + .Returns(new List { _indexerMock.Object }); + } + + [Test] + public void should_return_error_when_no_indexer_present() + { + Subject.Check().ShouldBeError(); + } + + [Test] + public void should_return_error_when_no_rss_supported_indexer_present() + { + GivenIndexer(false, true); + + Subject.Check().ShouldBeError(); + } + + [Test] + public void should_return_ok_when_rss_is_enabled() + { + GivenIndexer(true, false); + GivenRssEnabled(); + + Subject.Check().ShouldBeOk(); + } + + [Test] + public void should_return_error_if_rss_is_supported_but_disabled() + { + GivenIndexer(true, false); + + Subject.Check().ShouldBeError(); + } + + [Test] + public void should_return_filter_warning_if_rss_is_enabled_but_filtered() + { + GivenIndexer(true, false); + GivenRssFiltered(); + + Subject.Check().ShouldBeWarning("recent indexer errors"); + } + } +} diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerSearchCheckFixture.cs similarity index 50% rename from src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerCheckFixture.cs rename to src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerSearchCheckFixture.cs index 8bf06b14b..8cbc28b9d 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerCheckFixture.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/IndexerSearchCheckFixture.cs @@ -8,116 +8,85 @@ using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.HealthCheck.Checks { [TestFixture] - public class IndexerCheckFixture : CoreTest + public class IndexerSearchCheckFixture : CoreTest { private Mock _indexerMock; - private void GivenIndexer(bool supportsRss, bool supportsSearch) + [SetUp] + public void SetUp() { - _indexerMock = Mocker.GetMock(); - _indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss); - _indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch); - Mocker.GetMock() .Setup(s => s.GetAvailableProviders()) - .Returns(new List { _indexerMock.Object }); - - Mocker.GetMock() - .Setup(s => s.RssEnabled(true)) .Returns(new List()); Mocker.GetMock() - .Setup(s => s.SearchEnabled(true)) + .Setup(s => s.SearchEnabled(It.IsAny())) .Returns(new List()); } - private void GivenRssEnabled() + private void GivenIndexer(bool supportsRss, bool supportsSearch) { + _indexerMock = Mocker.GetMock(); + _indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss); + _indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch); + Mocker.GetMock() - .Setup(s => s.RssEnabled(true)) + .Setup(s => s.GetAvailableProviders()) .Returns(new List { _indexerMock.Object }); } private void GivenSearchEnabled() { Mocker.GetMock() - .Setup(s => s.SearchEnabled(true)) + .Setup(s => s.SearchEnabled(It.IsAny())) .Returns(new List { _indexerMock.Object }); } - [Test] - public void should_return_error_when_not_indexers_are_enabled() + private void GivenSearchFiltered() { Mocker.GetMock() - .Setup(s => s.GetAvailableProviders()) - .Returns(new List()); - - Subject.Check().ShouldBeError(); + .Setup(s => s.SearchEnabled(false)) + .Returns(new List { _indexerMock.Object }); } [Test] - public void should_return_warning_when_only_enabled_indexer_doesnt_support_search() + public void should_return_warning_when_no_indexer_present() { - GivenIndexer(true, false); - Subject.Check().ShouldBeWarning(); } [Test] - public void should_return_warning_when_only_enabled_indexer_doesnt_support_rss() + public void should_return_warning_when_no_search_supported_indexer_present() { - GivenIndexer(false, true); + GivenIndexer(true, false); Subject.Check().ShouldBeWarning(); } [Test] - public void should_return_ok_when_multiple_indexers_are_enabled() + public void should_return_ok_when_search_is_enabled() { - GivenRssEnabled(); - GivenSearchEnabled(); - - var indexer1 = Mocker.GetMock(); - indexer1.SetupGet(s => s.SupportsRss).Returns(true); - indexer1.SetupGet(s => s.SupportsSearch).Returns(true); - - var indexer2 = new Moq.Mock(); - indexer2.SetupGet(s => s.SupportsRss).Returns(true); - indexer2.SetupGet(s => s.SupportsSearch).Returns(false); - - Mocker.GetMock() - .Setup(s => s.GetAvailableProviders()) - .Returns(new List { indexer1.Object, indexer2.Object }); - - Subject.Check().ShouldBeOk(); - } - - [Test] - public void should_return_ok_when_indexer_supports_rss_and_search() - { - GivenIndexer(true, true); - GivenRssEnabled(); + GivenIndexer(false, true); GivenSearchEnabled(); Subject.Check().ShouldBeOk(); } [Test] - public void should_return_warning_if_rss_is_supported_but_disabled() + public void should_return_warning_if_search_is_supported_but_disabled() { - GivenIndexer(true, true); - GivenSearchEnabled(); + GivenIndexer(false, true); Subject.Check().ShouldBeWarning(); } [Test] - public void should_return_warning_if_search_is_supported_but_disabled() + public void should_return_filter_warning_if_search_is_enabled_but_filtered() { - GivenIndexer(true, true); - GivenRssEnabled(); + GivenIndexer(false, true); + GivenSearchFiltered(); - Subject.Check().ShouldBeWarning(); + Subject.Check().ShouldBeWarning("recent indexer errors"); } } } diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index 3d4033dda..22fcc354f 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -215,9 +215,10 @@ - + - + + diff --git a/src/NzbDrone.Core/HealthCheck/Checks/IndexerCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/IndexerCheck.cs deleted file mode 100644 index 199b81da3..000000000 --- a/src/NzbDrone.Core/HealthCheck/Checks/IndexerCheck.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Linq; -using NzbDrone.Common.Extensions; -using NzbDrone.Core.Indexers; - -namespace NzbDrone.Core.HealthCheck.Checks -{ - public class IndexerCheck : HealthCheckBase - { - private readonly IIndexerFactory _indexerFactory; - - public IndexerCheck(IIndexerFactory indexerFactory) - { - _indexerFactory = indexerFactory; - } - - public override HealthCheck Check() - { - var enabled = _indexerFactory.GetAvailableProviders(); - var rssEnabled = _indexerFactory.RssEnabled(); - var searchEnabled = _indexerFactory.SearchEnabled(); - - if (enabled.Empty()) - { - return new HealthCheck(GetType(), HealthCheckResult.Error, "No indexers are enabled"); - } - - if (enabled.All(i => i.SupportsRss == false)) - { - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not support RSS sync"); - } - - if (enabled.All(i => i.SupportsSearch == false)) - { - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not support searching"); - } - - if (rssEnabled.Empty()) - { - if (_indexerFactory.RssEnabled(false).Empty()) - { - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not have RSS sync enabled"); - } - - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers with RSS sync enabled are disabled due to recent failures"); - } - - if (searchEnabled.Empty()) - { - if (_indexerFactory.SearchEnabled(false).Empty()) - { - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers do not have searching enabled"); - } - - return new HealthCheck(GetType(), HealthCheckResult.Warning, "Enabled indexers with searching enabled are disabled due to recent failures"); - } - - return new HealthCheck(GetType()); - } - } -} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/IndexerRssCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/IndexerRssCheck.cs new file mode 100644 index 000000000..e0c9c9e5c --- /dev/null +++ b/src/NzbDrone.Core/HealthCheck/Checks/IndexerRssCheck.cs @@ -0,0 +1,35 @@ +using System.Linq; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Indexers; + +namespace NzbDrone.Core.HealthCheck.Checks +{ + public class IndexerRssCheck : HealthCheckBase + { + private readonly IIndexerFactory _indexerFactory; + + public IndexerRssCheck(IIndexerFactory indexerFactory) + { + _indexerFactory = indexerFactory; + } + + public override HealthCheck Check() + { + var enabled = _indexerFactory.RssEnabled(false); + + if (enabled.Empty()) + { + return new HealthCheck(GetType(), HealthCheckResult.Error, "No indexers available with RSS sync enabled, Sonarr will not grab new releases automatically"); + } + + var active = _indexerFactory.RssEnabled(true); + + if (active.Empty()) + { + return new HealthCheck(GetType(), HealthCheckResult.Warning, "All rss-capable indexers are temporarily unavailable due to recent indexer errors"); + } + + return new HealthCheck(GetType()); + } + } +} diff --git a/src/NzbDrone.Core/HealthCheck/Checks/IndexerSearchCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/IndexerSearchCheck.cs new file mode 100644 index 000000000..b2b81e4ec --- /dev/null +++ b/src/NzbDrone.Core/HealthCheck/Checks/IndexerSearchCheck.cs @@ -0,0 +1,35 @@ +using System.Linq; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Indexers; + +namespace NzbDrone.Core.HealthCheck.Checks +{ + public class IndexerSearchCheck : HealthCheckBase + { + private readonly IIndexerFactory _indexerFactory; + + public IndexerSearchCheck(IIndexerFactory indexerFactory) + { + _indexerFactory = indexerFactory; + } + + public override HealthCheck Check() + { + var enabled = _indexerFactory.SearchEnabled(false); + + if (enabled.Empty()) + { + return new HealthCheck(GetType(), HealthCheckResult.Warning, "No indexers available with Search enabled, Sonarr will not provide any search results"); + } + + var active = _indexerFactory.SearchEnabled(true); + + if (active.Empty()) + { + return new HealthCheck(GetType(), HealthCheckResult.Warning, "All search-capable indexers are temporarily unavailable due to recent indexer errors"); + } + + return new HealthCheck(GetType()); + } + } +} diff --git a/src/NzbDrone.Core/Indexers/XElementExtensions.cs b/src/NzbDrone.Core/Indexers/XElementExtensions.cs index 72da2790d..ef2b8b064 100644 --- a/src/NzbDrone.Core/Indexers/XElementExtensions.cs +++ b/src/NzbDrone.Core/Indexers/XElementExtensions.cs @@ -12,7 +12,7 @@ namespace NzbDrone.Core.Indexers { public static class XElementExtensions { - private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(XmlExtentions)); + private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(XmlExtensions)); public static readonly Regex RemoveTimeZoneRegex = new Regex(@"\s[A-Z]{2,4}$", RegexOptions.Compiled); diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 2c09a657b..7c8b4e2b7 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -548,8 +548,9 @@ + - +