|  | 
|  | 1 | +// ----------------------------------------------------------------------- | 
|  | 2 | +//  <copyright file="HealthCheckSpec.cs" company="Akka.NET Project"> | 
|  | 3 | +//      Copyright (C) 2013-2023 .NET Foundation <https://github.com/akkadotnet/akka.net> | 
|  | 4 | +//  </copyright> | 
|  | 5 | +// ----------------------------------------------------------------------- | 
|  | 6 | + | 
|  | 7 | +using System; | 
|  | 8 | +using System.Linq; | 
|  | 9 | +using System.Threading; | 
|  | 10 | +using System.Threading.Tasks; | 
|  | 11 | +using Akka.Hosting; | 
|  | 12 | +using Akka.Hosting.HealthChecks; | 
|  | 13 | +using Akka.Persistence.Journal; | 
|  | 14 | +using Akka.Persistence.Sql.Tests.Common.Containers; | 
|  | 15 | +using FluentAssertions; | 
|  | 16 | +using FluentAssertions.Extensions; | 
|  | 17 | +using Microsoft.Extensions.DependencyInjection; | 
|  | 18 | +using Microsoft.Extensions.Diagnostics.HealthChecks; | 
|  | 19 | +using Microsoft.Extensions.Hosting; | 
|  | 20 | +using Xunit; | 
|  | 21 | +using Xunit.Abstractions; | 
|  | 22 | + | 
|  | 23 | +namespace Akka.Persistence.Sql.Hosting.Tests | 
|  | 24 | +{ | 
|  | 25 | +    /// <summary> | 
|  | 26 | +    /// Validates that health checks are properly registered after the refactoring. | 
|  | 27 | +    /// </summary> | 
|  | 28 | +    public class HealthCheckSpec : Akka.Hosting.TestKit.TestKit, IClassFixture<SqliteContainer> | 
|  | 29 | +    { | 
|  | 30 | +        private readonly SqliteContainer _fixture; | 
|  | 31 | + | 
|  | 32 | +        public HealthCheckSpec(ITestOutputHelper output, SqliteContainer fixture) | 
|  | 33 | +            : base(nameof(HealthCheckSpec), output) | 
|  | 34 | +        { | 
|  | 35 | +            _fixture = fixture; | 
|  | 36 | + | 
|  | 37 | +            if (!_fixture.InitializeDbAsync().Wait(10.Seconds())) | 
|  | 38 | +                throw new Exception("Failed to clean up database in 10 seconds"); | 
|  | 39 | +        } | 
|  | 40 | + | 
|  | 41 | +        protected override void ConfigureServices(HostBuilderContext context, IServiceCollection services) | 
|  | 42 | +        { | 
|  | 43 | +            base.ConfigureServices(context, services); | 
|  | 44 | +            services.AddHealthChecks(); | 
|  | 45 | +        } | 
|  | 46 | + | 
|  | 47 | +        protected override void ConfigureAkka(AkkaConfigurationBuilder builder, IServiceProvider provider) | 
|  | 48 | +        { | 
|  | 49 | +            // Use the refactored WithSqlPersistence with health check registration | 
|  | 50 | +            builder.WithSqlPersistence( | 
|  | 51 | +                connectionString: _fixture.ConnectionString, | 
|  | 52 | +                providerName: _fixture.ProviderName, | 
|  | 53 | +                journalBuilder: journal => | 
|  | 54 | +                { | 
|  | 55 | +                    journal.WithHealthCheck(HealthStatus.Degraded); | 
|  | 56 | +                }, | 
|  | 57 | +                snapshotBuilder: snapshot => | 
|  | 58 | +                { | 
|  | 59 | +                    snapshot.WithHealthCheck(HealthStatus.Degraded); | 
|  | 60 | +                }); | 
|  | 61 | +        } | 
|  | 62 | + | 
|  | 63 | +        [Fact] | 
|  | 64 | +        public async Task Health_checks_should_be_registered_and_healthy() | 
|  | 65 | +        { | 
|  | 66 | +            // Arrange | 
|  | 67 | +            var healthCheckService = Host.Services.GetRequiredService<HealthCheckService>(); | 
|  | 68 | + | 
|  | 69 | +            // Act - run all health checks | 
|  | 70 | +            var healthReport = await healthCheckService.CheckHealthAsync(CancellationToken.None); | 
|  | 71 | + | 
|  | 72 | +            // Assert - verify that health checks are registered and healthy | 
|  | 73 | +            healthReport.Entries.Should().NotBeEmpty("health checks should be registered"); | 
|  | 74 | + | 
|  | 75 | +            // Debug: print all registered health checks (ALL of them, not just SQL) | 
|  | 76 | +            Output?.WriteLine($"Total health checks registered: {healthReport.Entries.Count}"); | 
|  | 77 | +            foreach (var entry in healthReport.Entries) | 
|  | 78 | +            { | 
|  | 79 | +                Output?.WriteLine($"  - {entry.Key}: {entry.Value.Status}"); | 
|  | 80 | +            } | 
|  | 81 | + | 
|  | 82 | +            // We should have exactly 2 health checks: journal and snapshot | 
|  | 83 | +            // Look for any Akka.Persistence-related health checks | 
|  | 84 | +            var persistenceHealthChecks = healthReport.Entries | 
|  | 85 | +                .Where(e => e.Key.Contains("Akka.Persistence", StringComparison.OrdinalIgnoreCase)) | 
|  | 86 | +                .ToList(); | 
|  | 87 | + | 
|  | 88 | +            persistenceHealthChecks.Should().HaveCount(2, | 
|  | 89 | +                "because we registered health checks for both journal and snapshot store"); | 
|  | 90 | + | 
|  | 91 | +            // Verify journal health check exists and is healthy | 
|  | 92 | +            var journalHealthCheck = persistenceHealthChecks | 
|  | 93 | +                .FirstOrDefault(e => e.Key.Contains("journal", StringComparison.OrdinalIgnoreCase)); | 
|  | 94 | + | 
|  | 95 | +            journalHealthCheck.Should().NotBeNull("journal health check should be registered"); | 
|  | 96 | +            journalHealthCheck.Value.Status.Should().Be(HealthStatus.Healthy, | 
|  | 97 | +                "SQL journal should be properly initialized"); | 
|  | 98 | + | 
|  | 99 | +            // Verify snapshot health check exists and is healthy | 
|  | 100 | +            var snapshotHealthCheck = persistenceHealthChecks | 
|  | 101 | +                .FirstOrDefault(e => e.Key.Contains("snapshot", StringComparison.OrdinalIgnoreCase)); | 
|  | 102 | + | 
|  | 103 | +            snapshotHealthCheck.Should().NotBeNull("snapshot health check should be registered"); | 
|  | 104 | +            snapshotHealthCheck.Value.Status.Should().Be(HealthStatus.Healthy, | 
|  | 105 | +                "SQL snapshot store should be properly initialized"); | 
|  | 106 | + | 
|  | 107 | +            // Verify overall health status | 
|  | 108 | +            healthReport.Status.Should().Be(HealthStatus.Healthy, | 
|  | 109 | +                "because all health checks should pass"); | 
|  | 110 | +        } | 
|  | 111 | +    } | 
|  | 112 | +} | 
0 commit comments