Fixed Indexer Health Checks and tests.

pull/6/head
Taloth Saldono 8 years ago
parent 37d5a3f2ad
commit 2abaef16f1

@ -2,7 +2,7 @@ using System;
namespace NzbDrone.Common.Extensions namespace NzbDrone.Common.Extensions
{ {
public static class Base64Extentions public static class Base64Extensions
{ {
public static string ToBase64(this byte[] bytes) public static string ToBase64(this byte[] bytes)
{ {

@ -5,7 +5,7 @@ using System.Xml.Linq;
namespace NzbDrone.Common.Extensions namespace NzbDrone.Common.Extensions
{ {
public static class XmlExtentions public static class XmlExtensions
{ {
public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName) public static IEnumerable<XElement> FindDecendants(this XContainer container, string localName)
{ {

@ -135,14 +135,14 @@
<Compile Include="Expansive\Tree.cs" /> <Compile Include="Expansive\Tree.cs" />
<Compile Include="Expansive\TreeNode.cs" /> <Compile Include="Expansive\TreeNode.cs" />
<Compile Include="Expansive\TreeNodeList.cs" /> <Compile Include="Expansive\TreeNodeList.cs" />
<Compile Include="Extensions\Base64Extentions.cs" /> <Compile Include="Extensions\Base64Extensions.cs" />
<Compile Include="Extensions\DateTimeExtensions.cs" /> <Compile Include="Extensions\DateTimeExtensions.cs" />
<Compile Include="Crypto\HashConverter.cs" /> <Compile Include="Crypto\HashConverter.cs" />
<Compile Include="Extensions\Int64Extensions.cs" /> <Compile Include="Extensions\Int64Extensions.cs" />
<Compile Include="Extensions\ObjectExtensions.cs" /> <Compile Include="Extensions\ObjectExtensions.cs" />
<Compile Include="Extensions\StreamExtensions.cs" /> <Compile Include="Extensions\StreamExtensions.cs" />
<Compile Include="Extensions\UrlExtensions.cs" /> <Compile Include="Extensions\UrlExtensions.cs" />
<Compile Include="Extensions\XmlExtentions.cs" /> <Compile Include="Extensions\XmlExtensions.cs" />
<Compile Include="HashUtil.cs" /> <Compile Include="HashUtil.cs" />
<Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" /> <Compile Include="Http\Dispatchers\CurlHttpDispatcher.cs" />
<Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" /> <Compile Include="Http\Dispatchers\FallbackHttpDispatcher.cs" />

@ -1,4 +1,5 @@
using FluentAssertions; using FluentAssertions;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.HealthCheck; using NzbDrone.Core.HealthCheck;
namespace NzbDrone.Core.Test.HealthCheck.Checks namespace NzbDrone.Core.Test.HealthCheck.Checks
@ -10,14 +11,24 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
result.Type.Should().Be(HealthCheckResult.Ok); 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); 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); result.Type.Should().Be(HealthCheckResult.Error);
if (message.IsNotNullOrWhiteSpace())
{
result.Message.Should().Contain(message);
}
} }
} }
} }

@ -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<IndexerRssCheck>
{
private Mock<IIndexer> _indexerMock;
[SetUp]
public void SetUp()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer>());
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled(It.IsAny<bool>()))
.Returns(new List<IIndexer>());
}
private void GivenIndexer(bool supportsRss, bool supportsSearch)
{
_indexerMock = Mocker.GetMock<IIndexer>();
_indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss);
_indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { _indexerMock.Object });
}
private void GivenRssEnabled()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled(It.IsAny<bool>()))
.Returns(new List<IIndexer> { _indexerMock.Object });
}
private void GivenRssFiltered()
{
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled(false))
.Returns(new List<IIndexer> { _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");
}
}
}

@ -8,116 +8,85 @@ using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.HealthCheck.Checks namespace NzbDrone.Core.Test.HealthCheck.Checks
{ {
[TestFixture] [TestFixture]
public class IndexerCheckFixture : CoreTest<IndexerCheck> public class IndexerSearchCheckFixture : CoreTest<IndexerSearchCheck>
{ {
private Mock<IIndexer> _indexerMock; private Mock<IIndexer> _indexerMock;
private void GivenIndexer(bool supportsRss, bool supportsSearch) [SetUp]
public void SetUp()
{ {
_indexerMock = Mocker.GetMock<IIndexer>();
_indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss);
_indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch);
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders()) .Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { _indexerMock.Object });
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled(true))
.Returns(new List<IIndexer>()); .Returns(new List<IIndexer>());
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.SearchEnabled(true)) .Setup(s => s.SearchEnabled(It.IsAny<bool>()))
.Returns(new List<IIndexer>()); .Returns(new List<IIndexer>());
} }
private void GivenRssEnabled() private void GivenIndexer(bool supportsRss, bool supportsSearch)
{ {
_indexerMock = Mocker.GetMock<IIndexer>();
_indexerMock.SetupGet(s => s.SupportsRss).Returns(supportsRss);
_indexerMock.SetupGet(s => s.SupportsSearch).Returns(supportsSearch);
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.RssEnabled(true)) .Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { _indexerMock.Object }); .Returns(new List<IIndexer> { _indexerMock.Object });
} }
private void GivenSearchEnabled() private void GivenSearchEnabled()
{ {
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.SearchEnabled(true)) .Setup(s => s.SearchEnabled(It.IsAny<bool>()))
.Returns(new List<IIndexer> { _indexerMock.Object }); .Returns(new List<IIndexer> { _indexerMock.Object });
} }
[Test] private void GivenSearchFiltered()
public void should_return_error_when_not_indexers_are_enabled()
{ {
Mocker.GetMock<IIndexerFactory>() Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders()) .Setup(s => s.SearchEnabled(false))
.Returns(new List<IIndexer>()); .Returns(new List<IIndexer> { _indexerMock.Object });
Subject.Check().ShouldBeError();
} }
[Test] [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(); Subject.Check().ShouldBeWarning();
} }
[Test] [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(); Subject.Check().ShouldBeWarning();
} }
[Test] [Test]
public void should_return_ok_when_multiple_indexers_are_enabled() public void should_return_ok_when_search_is_enabled()
{ {
GivenRssEnabled(); GivenIndexer(false, true);
GivenSearchEnabled();
var indexer1 = Mocker.GetMock<IIndexer>();
indexer1.SetupGet(s => s.SupportsRss).Returns(true);
indexer1.SetupGet(s => s.SupportsSearch).Returns(true);
var indexer2 = new Moq.Mock<IIndexer>();
indexer2.SetupGet(s => s.SupportsRss).Returns(true);
indexer2.SetupGet(s => s.SupportsSearch).Returns(false);
Mocker.GetMock<IIndexerFactory>()
.Setup(s => s.GetAvailableProviders())
.Returns(new List<IIndexer> { indexer1.Object, indexer2.Object });
Subject.Check().ShouldBeOk();
}
[Test]
public void should_return_ok_when_indexer_supports_rss_and_search()
{
GivenIndexer(true, true);
GivenRssEnabled();
GivenSearchEnabled(); GivenSearchEnabled();
Subject.Check().ShouldBeOk(); Subject.Check().ShouldBeOk();
} }
[Test] [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); GivenIndexer(false, true);
GivenSearchEnabled();
Subject.Check().ShouldBeWarning(); Subject.Check().ShouldBeWarning();
} }
[Test] [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); GivenIndexer(false, true);
GivenRssEnabled(); GivenSearchFiltered();
Subject.Check().ShouldBeWarning(); Subject.Check().ShouldBeWarning("recent indexer errors");
} }
} }
} }

@ -215,9 +215,10 @@
<Compile Include="HealthCheck\Checks\AppDataLocationFixture.cs" /> <Compile Include="HealthCheck\Checks\AppDataLocationFixture.cs" />
<Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\DownloadClientCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\DroneFactoryCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\DroneFactoryCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\HealthCheckFixtureExtentions.cs" /> <Compile Include="HealthCheck\Checks\HealthCheckFixtureExtensions.cs" />
<Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\ImportMechanismCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\IndexerCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\IndexerSearchCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\IndexerRssCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\MonoVersionCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\MonoVersionCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\IndexerStatusCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\IndexerStatusCheckFixture.cs" />
<Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" /> <Compile Include="HealthCheck\Checks\RootFolderCheckFixture.cs" />

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

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

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

@ -12,7 +12,7 @@ namespace NzbDrone.Core.Indexers
{ {
public static class XElementExtensions 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); public static readonly Regex RemoveTimeZoneRegex = new Regex(@"\s[A-Z]{2,4}$", RegexOptions.Compiled);

@ -548,8 +548,9 @@
<Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" /> <Compile Include="HealthCheck\Checks\DownloadClientCheck.cs" />
<Compile Include="HealthCheck\Checks\DroneFactoryCheck.cs" /> <Compile Include="HealthCheck\Checks\DroneFactoryCheck.cs" />
<Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" /> <Compile Include="HealthCheck\Checks\ImportMechanismCheck.cs" />
<Compile Include="HealthCheck\Checks\IndexerRssCheck.cs" />
<Compile Include="HealthCheck\Checks\IndexerStatusCheck.cs" /> <Compile Include="HealthCheck\Checks\IndexerStatusCheck.cs" />
<Compile Include="HealthCheck\Checks\IndexerCheck.cs" /> <Compile Include="HealthCheck\Checks\IndexerSearchCheck.cs" />
<Compile Include="HealthCheck\Checks\MediaInfoDllCheck.cs" /> <Compile Include="HealthCheck\Checks\MediaInfoDllCheck.cs" />
<Compile Include="HealthCheck\Checks\MonoVersionCheck.cs" /> <Compile Include="HealthCheck\Checks\MonoVersionCheck.cs" />
<Compile Include="HealthCheck\Checks\ProxyCheck.cs" /> <Compile Include="HealthCheck\Checks\ProxyCheck.cs" />

Loading…
Cancel
Save