Files
Umbraco-CMS/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/HostedServices/HealthCheckNotifierTests.cs
Paul Johnson 41a003e20e Ensure legacy scope returned when using legacy scope provider (#12465)
* Separate legacy scope provider interface and explicitly implement.

* Don't rely on legacy scope provider for existing tests.

* Assert correct type returned when using legacy scope provider.
2022-05-24 12:26:28 +02:00

194 lines
7.3 KiB
C#

// Copyright (c) Umbraco.
// See LICENSE for more details.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.HealthChecks;
using Umbraco.Cms.Core.HealthChecks.NotificationMethods;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Sync;
using Umbraco.Cms.Infrastructure.HostedServices;
using Umbraco.Cms.Tests.Common;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.HostedServices
{
[TestFixture]
public class HealthCheckNotifierTests
{
private Mock<IHealthCheckNotificationMethod> _mockNotificationMethod;
private const string Check1Id = "00000000-0000-0000-0000-000000000001";
private const string Check2Id = "00000000-0000-0000-0000-000000000002";
private const string Check3Id = "00000000-0000-0000-0000-000000000003";
[Test]
public async Task Does_Not_Execute_When_Not_Enabled()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(enabled: false);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[TestCase(RuntimeLevel.Boot)]
[TestCase(RuntimeLevel.Install)]
[TestCase(RuntimeLevel.Unknown)]
[TestCase(RuntimeLevel.Upgrade)]
[TestCase(RuntimeLevel.BootFailed)]
public async Task Does_Not_Execute_When_Runtime_State_Is_Not_Run(RuntimeLevel runtimeLevel)
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(runtimeLevel: runtimeLevel);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[Test]
public async Task Does_Not_Execute_When_Server_Role_Is_Subscriber()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(serverRole: ServerRole.Subscriber);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[Test]
public async Task Does_Not_Execute_When_Server_Role_Is_Unknown()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(serverRole: ServerRole.Unknown);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[Test]
public async Task Does_Not_Execute_When_Not_Main_Dom()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(isMainDom: false);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[Test]
public async Task Does_Not_Execute_With_No_Enabled_Notification_Methods()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier(notificationEnabled: false);
await sut.PerformExecuteAsync(null);
VerifyNotificationsNotSent();
}
[Test]
public async Task Executes_With_Enabled_Notification_Methods()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier();
await sut.PerformExecuteAsync(null);
VerifyNotificationsSent();
}
[Test]
public async Task Executes_Only_Enabled_Checks()
{
HealthCheckNotifier sut = CreateHealthCheckNotifier();
await sut.PerformExecuteAsync(null);
_mockNotificationMethod.Verify(
x => x.SendAsync(
It.Is<HealthCheckResults>(y => y.ResultsAsDictionary.Count == 1 && y.ResultsAsDictionary.ContainsKey("Check1"))), Times.Once);
}
private HealthCheckNotifier CreateHealthCheckNotifier(
bool enabled = true,
RuntimeLevel runtimeLevel = RuntimeLevel.Run,
ServerRole serverRole = ServerRole.Single,
bool isMainDom = true,
bool notificationEnabled = true)
{
var settings = new HealthChecksSettings
{
Notification = new HealthChecksNotificationSettings
{
Enabled = enabled,
DisabledChecks = new List<DisabledHealthCheckSettings>
{
new DisabledHealthCheckSettings { Id = Guid.Parse(Check3Id) }
}
},
DisabledChecks = new List<DisabledHealthCheckSettings>
{
new DisabledHealthCheckSettings { Id = Guid.Parse(Check2Id) }
}
};
var checks = new HealthCheckCollection(() => new List<HealthCheck>
{
new TestHealthCheck1(),
new TestHealthCheck2(),
new TestHealthCheck3(),
});
_mockNotificationMethod = new Mock<IHealthCheckNotificationMethod>();
_mockNotificationMethod.SetupGet(x => x.Enabled).Returns(notificationEnabled);
var notifications = new HealthCheckNotificationMethodCollection(() => new List<IHealthCheckNotificationMethod> { _mockNotificationMethod.Object });
var mockRunTimeState = new Mock<IRuntimeState>();
mockRunTimeState.SetupGet(x => x.Level).Returns(runtimeLevel);
var mockServerRegistrar = new Mock<IServerRoleAccessor>();
mockServerRegistrar.Setup(x => x.CurrentServerRole).Returns(serverRole);
var mockMainDom = new Mock<IMainDom>();
mockMainDom.SetupGet(x => x.IsMainDom).Returns(isMainDom);
var mockScopeProvider = new Mock<global::Umbraco.Cms.Infrastructure.Scoping.IScopeProvider>();
var mockLogger = new Mock<ILogger<HealthCheckNotifier>>();
var mockProfilingLogger = new Mock<IProfilingLogger>();
return new HealthCheckNotifier(
new TestOptionsMonitor<HealthChecksSettings>(settings),
checks,
notifications,
mockRunTimeState.Object,
mockServerRegistrar.Object,
mockMainDom.Object,
mockScopeProvider.Object,
mockLogger.Object,
mockProfilingLogger.Object,
Mock.Of<ICronTabParser>());
}
private void VerifyNotificationsNotSent() => VerifyNotificationsSentTimes(Times.Never());
private void VerifyNotificationsSent() => VerifyNotificationsSentTimes(Times.Once());
private void VerifyNotificationsSentTimes(Times times) => _mockNotificationMethod.Verify(x => x.SendAsync(It.IsAny<HealthCheckResults>()), times);
[HealthCheck(Check1Id, "Check1")]
private class TestHealthCheck1 : TestHealthCheck
{
}
[HealthCheck(Check2Id, "Check2")]
private class TestHealthCheck2 : TestHealthCheck
{
}
[HealthCheck(Check3Id, "Check3")]
private class TestHealthCheck3 : TestHealthCheck
{
}
private class TestHealthCheck : HealthCheck
{
public override HealthCheckStatus ExecuteAction(HealthCheckAction action) => new HealthCheckStatus("Check message");
public override async Task<IEnumerable<HealthCheckStatus>> GetStatus() => Enumerable.Empty<HealthCheckStatus>();
}
}
}