Adds abstraction around boot time checks for database availability (#19848)

* Adds abstraction around boot time checks for database availability.

* Addressed issues raised in code review.
This commit is contained in:
Andy Butland
2025-08-05 13:33:18 +02:00
committed by GitHub
parent 240e155d91
commit 0c22d512e2
5 changed files with 174 additions and 24 deletions

View File

@@ -0,0 +1,71 @@
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using NUnit.Framework;
using Umbraco.Cms.Core.Install.Models;
using Umbraco.Cms.Infrastructure.Persistence;
using Umbraco.Cms.Persistence.SqlServer.Services;
namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Persistence;
[TestFixture]
public class DefaultDatabaseAvailabilityCheckTests
{
[Test]
public void IsDatabaseAvailable_WithDatabaseUnavailable_ReturnsFalse()
{
var mockDatabaseFactory = new Mock<IUmbracoDatabaseFactory>();
mockDatabaseFactory
.Setup(x => x.CanConnect)
.Returns(false);
var sut = CreateDefaultDatabaseAvailabilityCheck();
var result = sut.IsDatabaseAvailable(mockDatabaseFactory.Object);
Assert.IsFalse(result);
}
[Test]
public void IsDatabaseAvailable_WithDatabaseImmediatelyAvailable_ReturnsTrue()
{
var mockDatabaseFactory = new Mock<IUmbracoDatabaseFactory>();
mockDatabaseFactory
.Setup(x => x.CanConnect)
.Returns(true);
var sut = CreateDefaultDatabaseAvailabilityCheck();
var result = sut.IsDatabaseAvailable(mockDatabaseFactory.Object);
Assert.IsTrue(result);
}
[TestCase(5, true)]
[TestCase(6, false)]
public void IsDatabaseAvailable_WithDatabaseImmediatelyAvailableAfterMultipleAttempts_ReturnsExpectedResult(int attemptsUntilConnection, bool expectedResult)
{
if (attemptsUntilConnection < 1)
{
throw new ArgumentException($"{nameof(attemptsUntilConnection)} must be greater than or equal to 1.", nameof(attemptsUntilConnection));
}
var attemptResults = new Queue<bool>();
for (var i = 0; i < attemptsUntilConnection - 1; i++)
{
attemptResults.Enqueue(false);
}
attemptResults.Enqueue(true);
var mockDatabaseFactory = new Mock<IUmbracoDatabaseFactory>();
mockDatabaseFactory
.Setup(x => x.CanConnect)
.Returns(attemptResults.Dequeue);
var sut = CreateDefaultDatabaseAvailabilityCheck();
var result = sut.IsDatabaseAvailable(mockDatabaseFactory.Object);
Assert.AreEqual(expectedResult, result);
}
private static DefaultDatabaseAvailabilityCheck CreateDefaultDatabaseAvailabilityCheck()
=> new(new NullLogger<DefaultDatabaseAvailabilityCheck>())
{
AttemptDelayMilliseconds = 1 // Set to 1 ms for faster tests.
};
}