File: DependencyInjection\HealthChecksBuilderTest.cs
Web Access
Project: src\src\HealthChecks\HealthChecks\test\Microsoft.Extensions.Diagnostics.HealthChecks.Tests.csproj (Microsoft.Extensions.Diagnostics.HealthChecks.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Options;
using Xunit;
 
namespace Microsoft.Extensions.DependencyInjection;
 
// Integration tests for extension methods on IHealthCheckBuilder
//
// We test the longest overload of each 'family' of Add...Check methods, since they chain to each other.
public class HealthChecksBuilderTest
{
    [Fact]
    public void AddCheck_Instance()
    {
        // Arrange
        var instance = new DelegateHealthCheck((_) =>
        {
            return Task.FromResult(HealthCheckResult.Healthy());
        });
 
        var services = CreateServices();
        services.AddHealthChecks().AddCheck("test", failureStatus: HealthStatus.Degraded, tags: new[] { "tag", }, instance: instance);
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Degraded, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.Same(instance, registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddCheck_T_TypeActivated()
    {
        // Arrange
        var services = CreateServices();
        services.AddHealthChecks().AddCheck<TestHealthCheck>("test", failureStatus: HealthStatus.Degraded, tags: new[] { "tag", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Degraded, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.IsType<TestHealthCheck>(registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddCheck_T_Service()
    {
        // Arrange
        var instance = new TestHealthCheck();
 
        var services = CreateServices();
        services.AddSingleton(instance);
        services.AddHealthChecks().AddCheck<TestHealthCheck>("test", failureStatus: HealthStatus.Degraded, tags: new[] { "tag", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Degraded, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.Same(instance, registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddTypeActivatedCheck()
    {
        // Arrange
        var services = CreateServices();
        services
            .AddHealthChecks()
            .AddTypeActivatedCheck<TestHealthCheckWithArgs>("test", failureStatus: HealthStatus.Degraded, tags: new[] { "tag", }, args: new object[] { 5, "hi", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Degraded, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
 
        var check = Assert.IsType<TestHealthCheckWithArgs>(registration.Factory(serviceProvider));
        Assert.Equal(5, check.I);
        Assert.Equal("hi", check.S);
    }
 
    [Fact]
    public void AddDelegateCheck_NoArg()
    {
        // Arrange
        var services = CreateServices();
        services.AddHealthChecks().AddCheck("test", tags: new[] { "tag", }, check: () =>
        {
            return HealthCheckResult.Healthy();
        });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Unhealthy, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.IsType<DelegateHealthCheck>(registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddDelegateCheck_CancellationToken()
    {
        // Arrange
        var services = CreateServices();
        services.AddHealthChecks().AddCheck("test", (_) =>
        {
            return HealthCheckResult.Degraded();
        }, tags: new[] { "tag", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Unhealthy, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.IsType<DelegateHealthCheck>(registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddAsyncDelegateCheck_NoArg()
    {
        // Arrange
        var services = CreateServices();
        services.AddHealthChecks().AddAsyncCheck("test", () =>
        {
            return Task.FromResult(HealthCheckResult.Healthy());
        }, tags: new[] { "tag", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Unhealthy, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.IsType<DelegateHealthCheck>(registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void AddAsyncDelegateCheck_CancellationToken()
    {
        // Arrange
        var services = CreateServices();
        services.AddHealthChecks().AddAsyncCheck("test", (_) =>
        {
            return Task.FromResult(HealthCheckResult.Unhealthy());
        }, tags: new[] { "tag", });
 
        var serviceProvider = services.BuildServiceProvider();
 
        // Act
        var options = serviceProvider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
 
        // Assert
        var registration = Assert.Single(options.Registrations);
        Assert.Equal("test", registration.Name);
        Assert.Equal(HealthStatus.Unhealthy, registration.FailureStatus);
        Assert.Equal<string>(new[] { "tag", }, registration.Tags);
        Assert.IsType<DelegateHealthCheck>(registration.Factory(serviceProvider));
    }
 
    [Fact]
    public void ChecksCanBeRegisteredInMultipleCallsToAddHealthChecks()
    {
        var services = new ServiceCollection();
        services
            .AddHealthChecks()
            .AddAsyncCheck("Foo", () => Task.FromResult(HealthCheckResult.Healthy()));
        services
            .AddHealthChecks()
            .AddAsyncCheck("Bar", () => Task.FromResult(HealthCheckResult.Healthy()));
 
        // Act
        var options = services.BuildServiceProvider().GetRequiredService<IOptions<HealthCheckServiceOptions>>();
 
        // Assert
        Assert.Collection(
            options.Value.Registrations,
            actual => Assert.Equal("Foo", actual.Name),
            actual => Assert.Equal("Bar", actual.Name));
    }
 
    private IServiceCollection CreateServices()
    {
        var services = new ServiceCollection();
        services.AddLogging();
        services.AddOptions();
        return services;
    }
 
    private class TestHealthCheck : IHealthCheck
    {
        public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            throw new System.NotImplementedException();
        }
    }
 
    private class TestHealthCheckWithArgs : IHealthCheck
    {
        public TestHealthCheckWithArgs(int i, string s)
        {
            I = i;
            S = s;
        }
 
        public int I { get; set; }
 
        public string S { get; set; }
 
        public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            throw new System.NotImplementedException();
        }
    }
}