using Elsa.Workflows.Runtime.HealthChecks; using Medallion.Threading; using Microsoft.Extensions.Diagnostics.HealthChecks; using NSubstitute; namespace Elsa.Workflows.Runtime.UnitTests.HealthChecks; public class ElsaDistributedLockHealthCheckTests { private static readonly TimeSpan ExpectedLockAcquisitionTimeout = TimeSpan.FromSeconds(1); private readonly IDistributedLockProvider _distributedLockProvider = Substitute.For(); private readonly IDistributedLock _distributedLock = Substitute.For(); private readonly ElsaDistributedLockHealthCheck _sut; public ElsaDistributedLockHealthCheckTests() { _distributedLockProvider.CreateLock(Arg.Any()).Returns(_distributedLock); _distributedLock.TryAcquireAsync(Arg.Any(), Arg.Any()) .Returns(new ValueTask(Substitute.For())); _sut = new ElsaDistributedLockHealthCheck(_distributedLockProvider); } [Fact] public async Task ReturnsHealthyWhenProbeLockCanBeAcquired() { var result = await _sut.CheckHealthAsync(new HealthCheckContext()); Assert.Equal(HealthStatus.Healthy, result.Status); Assert.Equal("distributed-locks", result.Data["category"]); _distributedLockProvider.Received(1).CreateLock(Arg.Is(x => x.StartsWith("elsa-health-check-", StringComparison.Ordinal))); await _distributedLock.Received(1).TryAcquireAsync(ExpectedLockAcquisitionTimeout, Arg.Any()); } [Fact] public async Task ReturnsDegradedWhenProbeLockCannotBeAcquired() { _distributedLock.TryAcquireAsync(Arg.Any(), Arg.Any()) .Returns(new ValueTask((IDistributedSynchronizationHandle?)null)); var result = await _sut.CheckHealthAsync(new HealthCheckContext()); Assert.Equal(HealthStatus.Degraded, result.Status); Assert.Equal("distributed-locks", result.Data["category"]); } [Fact] public async Task ReturnsUnhealthyWhenProviderThrows() { _distributedLockProvider.CreateLock(Arg.Any()).Returns(_ => throw new InvalidOperationException("lock backend unavailable")); var result = await _sut.CheckHealthAsync(new HealthCheckContext()); Assert.Equal(HealthStatus.Unhealthy, result.Status); Assert.Equal("distributed-locks", result.Data["category"]); } }