From fb21a02212eb7216144cc887b213e10fb783cbd7 Mon Sep 17 00:00:00 2001 From: Odonno Date: Mon, 25 Sep 2023 18:24:20 +0200 Subject: [PATCH] Add package for SurrealDB --- AspNetCore.Diagnostics.HealthChecks.sln | 40 +++++-- README.md | 2 + build/versions.props | 1 + .../SurrealDbHealthCheckBuilderExtensions.cs | 111 ++++++++++++++++++ .../HealthChecks.SurrealDb.csproj | 15 +++ .../SurrealDbHealthCheck.cs | 40 +++++++ .../SurrealDbHealthCheckOptions.cs | 25 ++++ .../DependencyInjection/RegistrationTests.cs | 89 ++++++++++++++ .../Functional/SurrealDbHealthCheckTests.cs | 56 +++++++++ .../HealthChecks.SurrealDb.Tests.csproj | 11 ++ .../HealthChecks.SurrealDb.approved.txt | 24 ++++ 11 files changed, 401 insertions(+), 13 deletions(-) create mode 100644 src/HealthChecks.SurrealDb/DependencyInjection/SurrealDbHealthCheckBuilderExtensions.cs create mode 100644 src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj create mode 100644 src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs create mode 100644 src/HealthChecks.SurrealDb/SurrealDbHealthCheckOptions.cs create mode 100644 test/HealthChecks.SurrealDb.Tests/DependencyInjection/RegistrationTests.cs create mode 100644 test/HealthChecks.SurrealDb.Tests/Functional/SurrealDbHealthCheckTests.cs create mode 100644 test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj create mode 100644 test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.approved.txt diff --git a/AspNetCore.Diagnostics.HealthChecks.sln b/AspNetCore.Diagnostics.HealthChecks.sln index 749a194b07..038e7db98a 100644 --- a/AspNetCore.Diagnostics.HealthChecks.sln +++ b/AspNetCore.Diagnostics.HealthChecks.sln @@ -247,9 +247,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.AzureDigitalTw EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Aws.Sqs", "src\HealthChecks.Aws.Sqs\HealthChecks.Aws.Sqs.csproj", "{3E28B63C-814E-46C9-ADBF-7357997148F5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.AzureApplicationInsights", "src\HealthChecks.AzureApplicationInsights\HealthChecks.AzureApplicationInsights.csproj", "{97C43FFC-0A48-47C7-93EE-7382C2989AAE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.AzureApplicationInsights", "src\HealthChecks.AzureApplicationInsights\HealthChecks.AzureApplicationInsights.csproj", "{97C43FFC-0A48-47C7-93EE-7382C2989AAE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.AzureApplicationInsights.Tests", "test\HealthChecks.AzureApplicationInsights.Tests\HealthChecks.AzureApplicationInsights.Tests.csproj", "{78902D9E-CD1A-4FB7-B752-A3471A2DD457}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.AzureApplicationInsights.Tests", "test\HealthChecks.AzureApplicationInsights.Tests\HealthChecks.AzureApplicationInsights.Tests.csproj", "{78902D9E-CD1A-4FB7-B752-A3471A2DD457}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Aws.Sqs.Tests", "test\HealthChecks.Aws.Sqs.Tests\HealthChecks.Aws.Sqs.Tests.csproj", "{EFA76A2C-CA0E-42BC-8215-AEEB16414947}" EndProject @@ -283,7 +283,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.UI.Data.Tests" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Dapr", "src\HealthChecks.Dapr\HealthChecks.Dapr.csproj", "{716C2E59-6BB4-49A1-B685-9958B7EF0F3B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthChecks.Dapr.Tests", "test\HealthChecks.Dapr.Tests\HealthChecks.Dapr.Tests.csproj", "{1C2085FA-2D33-459B-945E-337323485E16}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.Dapr.Tests", "test\HealthChecks.Dapr.Tests\HealthChecks.Dapr.Tests.csproj", "{1C2085FA-2D33-459B-945E-337323485E16}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.SurrealDb", "src\HealthChecks.SurrealDb\HealthChecks.SurrealDb.csproj", "{97DAA09F-E0FA-4D5B-A72B-896161E570DA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HealthChecks.SurrealDb.Tests", "test\HealthChecks.SurrealDb.Tests\HealthChecks.SurrealDb.Tests.csproj", "{44BB97EE-88DB-4C9B-8195-2C6D889AE391}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -715,18 +719,18 @@ Global {7052C706-4B1A-4167-A33A-DF3E9FBCFE6B}.Debug|Any CPU.Build.0 = Debug|Any CPU {7052C706-4B1A-4167-A33A-DF3E9FBCFE6B}.Release|Any CPU.ActiveCfg = Release|Any CPU {7052C706-4B1A-4167-A33A-DF3E9FBCFE6B}.Release|Any CPU.Build.0 = Release|Any CPU - {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Debug|Any CPU.Build.0 = Debug|Any CPU - {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Release|Any CPU.ActiveCfg = Release|Any CPU - {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Release|Any CPU.Build.0 = Release|Any CPU - {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Release|Any CPU.Build.0 = Release|Any CPU {3E28B63C-814E-46C9-ADBF-7357997148F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3E28B63C-814E-46C9-ADBF-7357997148F5}.Debug|Any CPU.Build.0 = Debug|Any CPU {3E28B63C-814E-46C9-ADBF-7357997148F5}.Release|Any CPU.ActiveCfg = Release|Any CPU {3E28B63C-814E-46C9-ADBF-7357997148F5}.Release|Any CPU.Build.0 = Release|Any CPU + {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97C43FFC-0A48-47C7-93EE-7382C2989AAE}.Release|Any CPU.Build.0 = Release|Any CPU + {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Debug|Any CPU.Build.0 = Debug|Any CPU + {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Release|Any CPU.ActiveCfg = Release|Any CPU + {78902D9E-CD1A-4FB7-B752-A3471A2DD457}.Release|Any CPU.Build.0 = Release|Any CPU {EFA76A2C-CA0E-42BC-8215-AEEB16414947}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EFA76A2C-CA0E-42BC-8215-AEEB16414947}.Debug|Any CPU.Build.0 = Debug|Any CPU {EFA76A2C-CA0E-42BC-8215-AEEB16414947}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -795,6 +799,14 @@ Global {1C2085FA-2D33-459B-945E-337323485E16}.Debug|Any CPU.Build.0 = Debug|Any CPU {1C2085FA-2D33-459B-945E-337323485E16}.Release|Any CPU.ActiveCfg = Release|Any CPU {1C2085FA-2D33-459B-945E-337323485E16}.Release|Any CPU.Build.0 = Release|Any CPU + {97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97DAA09F-E0FA-4D5B-A72B-896161E570DA}.Release|Any CPU.Build.0 = Release|Any CPU + {44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Release|Any CPU.ActiveCfg = Release|Any CPU + {44BB97EE-88DB-4C9B-8195-2C6D889AE391}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -906,9 +918,9 @@ Global {FF492215-60BC-40C6-B118-D22DF9063547} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} {247EF2E5-F4B9-47D4-BB89-27860DF53D5F} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} {7052C706-4B1A-4167-A33A-DF3E9FBCFE6B} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} - {78902D9E-CD1A-4FB7-B752-A3471A2DD457} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} - {97C43FFC-0A48-47C7-93EE-7382C2989AAE} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} {3E28B63C-814E-46C9-ADBF-7357997148F5} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} + {97C43FFC-0A48-47C7-93EE-7382C2989AAE} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} + {78902D9E-CD1A-4FB7-B752-A3471A2DD457} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} {EFA76A2C-CA0E-42BC-8215-AEEB16414947} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} {AE41DB38-93BC-48A7-8841-163E5E13CE8D} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} {CB1A7B68-E24A-4729-9401-606F3A914586} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} @@ -926,6 +938,8 @@ Global {93DEEAD7-9A89-48C6-AD42-103AEADBCACE} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} {716C2E59-6BB4-49A1-B685-9958B7EF0F3B} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} {1C2085FA-2D33-459B-945E-337323485E16} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} + {97DAA09F-E0FA-4D5B-A72B-896161E570DA} = {2A3FD988-2BB8-43CF-B3A2-B70E648259D4} + {44BB97EE-88DB-4C9B-8195-2C6D889AE391} = {FF4414C2-8863-4ADA-8A1D-4B9F25C361FE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {2B8C62A1-11B6-469F-874C-A02443256568} diff --git a/README.md b/README.md index 19112a7243..7f13c79894 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ HealthChecks packages include health checks for: | Solr | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Solr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Solr) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Solr)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Solr) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/solr)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/solr) | Sqlite | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Sqlite)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Sqlite) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Sqlite)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Sqlite) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/sqlite)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/sqlite) | Sql Server | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.SqlServer)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SqlServer) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.SqlServer)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SqlServer) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/sqlserver)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/sqlserver) +| SurrealDb | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.SurrealDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SurrealDb) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.SurrealDb)](https://www.nuget.org/packages/AspNetCore.HealthChecks.SurrealDb) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/surrealdb)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/surrealdb) | System | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.System)](https://www.nuget.org/packages/AspNetCore.HealthChecks.System) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.System)](https://www.nuget.org/packages/AspNetCore.HealthChecks.System) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/system)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/system) | Disk Storage, Folder, Private Memory, Virtual Memory, Process, Windows Service | | Uris | [![Nuget](https://img.shields.io/nuget/dt/AspNetCore.HealthChecks.Uris)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Uris) | [![Nuget](https://img.shields.io/nuget/v/AspNetCore.HealthChecks.Uris)](https://www.nuget.org/packages/AspNetCore.HealthChecks.Uris) | [![view](https://img.shields.io/github/issues/Xabaril/AspNetCore.Diagnostics.HealthChecks/uris)](https://github.com/Xabaril/AspNetCore.Diagnostics.HealthChecks/labels/uris) | Single uri and uri groups | @@ -160,6 +161,7 @@ Install-Package AspNetCore.HealthChecks.SignalR Install-Package AspNetCore.HealthChecks.Solr Install-Package AspNetCore.HealthChecks.SqLite Install-Package AspNetCore.HealthChecks.SqlServer +Install-Package AspNetCore.HealthChecks.SurrealDb Install-Package AspNetCore.HealthChecks.System Install-Package AspNetCore.HealthChecks.Uris ``` diff --git a/build/versions.props b/build/versions.props index b3aaa42ad7..74ed1c88de 100644 --- a/build/versions.props +++ b/build/versions.props @@ -51,6 +51,7 @@ 7.0.0 7.0.0 7.0.0 + 7.0.0 7.0.0 7.0.0 7.0.0 diff --git a/src/HealthChecks.SurrealDb/DependencyInjection/SurrealDbHealthCheckBuilderExtensions.cs b/src/HealthChecks.SurrealDb/DependencyInjection/SurrealDbHealthCheckBuilderExtensions.cs new file mode 100644 index 0000000000..d9d1fabf66 --- /dev/null +++ b/src/HealthChecks.SurrealDb/DependencyInjection/SurrealDbHealthCheckBuilderExtensions.cs @@ -0,0 +1,111 @@ +using HealthChecks.SurrealDb; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using SurrealDb.Net; + +namespace Microsoft.Extensions.DependencyInjection; + +/// +/// Extension methods to configure . +/// +public static class SurrealDbHealthCheckBuilderExtensions +{ + private const string NAME = "surrealdb"; + + /// + /// Add a health check for SurrealDB. + /// + /// The . + /// The SurrealDB connection string to be used. + /// An optional action to allow additional SQL Server specific configuration. + /// The health check name. Optional. If null the type name 'surrealdb' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddSurreal( + this IHealthChecksBuilder builder, + string connectionString, + Action? configure = null, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + return builder.AddSurreal(_ => connectionString, configure, name, failureStatus, tags, timeout); + } + + /// + /// Add a health check for SurrealDB. + /// + /// The . + /// A factory to build the SurrealDB connection string to use. + /// An optional action to allow additional SQL Server specific configuration. + /// The health check name. Optional. If null the type name 'surrealdb' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddSurreal( + this IHealthChecksBuilder builder, + Func connectionStringFactory, + Action? configure = null, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(connectionStringFactory); + + return builder.Add(new HealthCheckRegistration( + name ?? NAME, + sp => + { + var options = new SurrealDbHealthCheckOptions + { + ConnectionString = connectionStringFactory(sp), + Configure = configure, + }; + return new SurrealDbHealthCheck(options); + }, + failureStatus, + tags, + timeout)); + } + + /// + /// Add a health check for SurrealDB. + /// + /// The . + /// Options for health check. + /// The health check name. Optional. If null the type name 'surrealdb' will be used for the name. + /// + /// The that should be reported when the health check fails. Optional. If null then + /// the default status of will be reported. + /// + /// A list of tags that can be used to filter sets of health checks. Optional. + /// An optional representing the timeout of the check. + /// The specified . + public static IHealthChecksBuilder AddSurreal( + this IHealthChecksBuilder builder, + SurrealDbHealthCheckOptions options, + string? name = default, + HealthStatus? failureStatus = default, + IEnumerable? tags = default, + TimeSpan? timeout = default) + { + Guard.ThrowIfNull(options); + + return builder.Add(new HealthCheckRegistration( + name ?? NAME, + _ => new SurrealDbHealthCheck(options), + failureStatus, + tags, + timeout)); + } +} diff --git a/src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj b/src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj new file mode 100644 index 0000000000..58c98c05dd --- /dev/null +++ b/src/HealthChecks.SurrealDb/HealthChecks.SurrealDb.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.1 + $(PackageTags);SurrealDb + HealthChecks.SurrealDb is the health check package for SurrealDB. + $(HealthCheckSurrealDb) + + + + + + + + diff --git a/src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs b/src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs new file mode 100644 index 0000000000..cbbacdc0ed --- /dev/null +++ b/src/HealthChecks.SurrealDb/SurrealDbHealthCheck.cs @@ -0,0 +1,40 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using SurrealDb.Net; + +namespace HealthChecks.SurrealDb; + +/// +/// A health check for SurrealDb services. +/// +public class SurrealDbHealthCheck : IHealthCheck +{ + private readonly SurrealDbHealthCheckOptions _options; + + public SurrealDbHealthCheck(SurrealDbHealthCheckOptions options) + { + Guard.ThrowIfNull(options.ConnectionString, true); + _options = options; + } + + /// + public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default) + { + try + { + using var client = new SurrealDbClient(_options.ConnectionString); + + _options.Configure?.Invoke(client); + await client.Connect(cancellationToken).ConfigureAwait(false); + + bool result = await client.Health(cancellationToken).ConfigureAwait(false); + + return _options.HealthCheckResultBuilder == null + ? HealthCheckResult.Healthy() + : _options.HealthCheckResultBuilder(result); + } + catch (Exception ex) + { + return new HealthCheckResult(context.Registration.FailureStatus, exception: ex); + } + } +} diff --git a/src/HealthChecks.SurrealDb/SurrealDbHealthCheckOptions.cs b/src/HealthChecks.SurrealDb/SurrealDbHealthCheckOptions.cs new file mode 100644 index 0000000000..709af9c982 --- /dev/null +++ b/src/HealthChecks.SurrealDb/SurrealDbHealthCheckOptions.cs @@ -0,0 +1,25 @@ +using Microsoft.Extensions.Diagnostics.HealthChecks; +using SurrealDb.Net; + +namespace HealthChecks.SurrealDb; + +/// +/// Options for . +/// +public class SurrealDbHealthCheckOptions +{ + /// + /// The Sql Server connection string to be used. + /// + public string ConnectionString { get; set; } = null!; + + /// + /// An optional action executed before the connection is opened in the health check. + /// + public Action? Configure { get; set; } + + /// + /// An optional delegate to build health check result. + /// + public Func? HealthCheckResultBuilder { get; set; } +} diff --git a/test/HealthChecks.SurrealDb.Tests/DependencyInjection/RegistrationTests.cs b/test/HealthChecks.SurrealDb.Tests/DependencyInjection/RegistrationTests.cs new file mode 100644 index 0000000000..b5f812c705 --- /dev/null +++ b/test/HealthChecks.SurrealDb.Tests/DependencyInjection/RegistrationTests.cs @@ -0,0 +1,89 @@ +using SurrealDb.Net; + +namespace HealthChecks.SurrealDb.Tests.DependencyInjection; + +public class surrealdb_registration_should +{ + [Fact] + public void add_health_check_when_properly_configured() + { + var services = new ServiceCollection() + .AddHealthChecks() + .AddSurreal("connectionstring") + .Services; + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("surrealdb"); + check.ShouldBeOfType(); + } + + [Fact] + public void invoke_beforeOpen_when_defined() + { + var services = new ServiceCollection(); + bool invoked = false; + const string connectionstring = "Server=http://localhost:8000;Namespace=test;Database=test;Username=root;Password=root"; + void beforeOpen(ISurrealDbClient client) + { + invoked = true; + client.Uri.AbsoluteUri.ShouldBe("http://localhost:8000"); + } + services.AddHealthChecks() + .AddSurreal(connectionstring, configure: beforeOpen); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + Record.ExceptionAsync(() => check.CheckHealthAsync(new HealthCheckContext())).GetAwaiter().GetResult(); + invoked.ShouldBeTrue(); + } + + [Fact] + public void add_named_health_check_when_properly_configured() + { + var services = new ServiceCollection() + .AddHealthChecks() + .AddSurreal("connectionstring", name: "my-surrealdb-1") + .Services; + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("my-surrealdb-1"); + check.ShouldBeOfType(); + } + + [Fact] + public void add_health_check_with_connection_string_factory_when_properly_configured() + { + var services = new ServiceCollection(); + bool factoryCalled = false; + services.AddHealthChecks() + .AddSurreal(_ => + { + factoryCalled = true; + return "connectionstring"; + }); + + using var serviceProvider = services.BuildServiceProvider(); + var options = serviceProvider.GetRequiredService>(); + + var registration = options.Value.Registrations.First(); + var check = registration.Factory(serviceProvider); + + registration.Name.ShouldBe("surrealdb"); + check.ShouldBeOfType(); + factoryCalled.ShouldBeTrue(); + } +} diff --git a/test/HealthChecks.SurrealDb.Tests/Functional/SurrealDbHealthCheckTests.cs b/test/HealthChecks.SurrealDb.Tests/Functional/SurrealDbHealthCheckTests.cs new file mode 100644 index 0000000000..e84f776548 --- /dev/null +++ b/test/HealthChecks.SurrealDb.Tests/Functional/SurrealDbHealthCheckTests.cs @@ -0,0 +1,56 @@ +using System.Net; + +namespace HealthChecks.SurrealDb.Tests.Functional; + +public class surrealdb_healthcheck_should +{ + [Fact] + public async Task be_healthy_if_surrealdb_is_available() + { + var connectionString = "Server=http://localhost:8000;Namespace=test;Database=test;Username=root;Password=root"; + + var webHostBuilder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddHealthChecks() + .AddSurreal(connectionString, tags: new string[] { "surrealdb" }); + }) + .Configure(app => + { + app.UseHealthChecks("/health", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("surrealdb") + }); + }); + + using var server = new TestServer(webHostBuilder); + + using var response = await server.CreateRequest("/health").GetAsync().ConfigureAwait(false); + + response.StatusCode.ShouldBe(HttpStatusCode.OK); + } + + [Fact] + public async Task be_unhealthy_if_surrealdb_is_not_available() + { + var webHostBuilder = new WebHostBuilder() + .ConfigureServices(services => + { + services.AddHealthChecks() + .AddSurreal("Server=http://200.0.0.100:1234;Namespace=test;Database=test;Username=root;Password=root", tags: new string[] { "surrealdb" }); + }) + .Configure(app => + { + app.UseHealthChecks("/health", new HealthCheckOptions + { + Predicate = r => r.Tags.Contains("surrealdb") + }); + }); + + using var server = new TestServer(webHostBuilder); + + using var response = await server.CreateRequest("/health").GetAsync().ConfigureAwait(false); + + response.StatusCode.ShouldBe(HttpStatusCode.ServiceUnavailable); + } +} diff --git a/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj b/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj new file mode 100644 index 0000000000..56fdcbe879 --- /dev/null +++ b/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.Tests.csproj @@ -0,0 +1,11 @@ + + + + net6.0;net7.0 + + + + + + + diff --git a/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.approved.txt b/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.approved.txt new file mode 100644 index 0000000000..7f6eef80ff --- /dev/null +++ b/test/HealthChecks.SurrealDb.Tests/HealthChecks.SurrealDb.approved.txt @@ -0,0 +1,24 @@ +namespace HealthChecks.SurrealDb +{ + public class SurrealDbHealthCheck : Microsoft.Extensions.Diagnostics.HealthChecks.IHealthCheck + { + public SurrealDbHealthCheck(HealthChecks.SurrealDb.SurrealDbHealthCheckOptions options) { } + public System.Threading.Tasks.Task CheckHealthAsync(Microsoft.Extensions.Diagnostics.HealthChecks.HealthCheckContext context, System.Threading.CancellationToken cancellationToken = default) { } + } + public class SurrealDbHealthCheckOptions + { + public SurrealDbHealthCheckOptions() { } + public System.Action? Configure { get; set; } + public string ConnectionString { get; set; } + public System.Func? HealthCheckResultBuilder { get; set; } + } +} +namespace Microsoft.Extensions.DependencyInjection +{ + public static class SurrealDbHealthCheckBuilderExtensions + { + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddSurreal(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, HealthChecks.SqlServer.SqlServerHealthCheckOptions options, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddSurreal(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, System.Func connectionStringFactory, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + public static Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder AddSurreal(this Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder builder, string connectionString, System.Action? configure = null, string? name = null, Microsoft.Extensions.Diagnostics.HealthChecks.HealthStatus? failureStatus = default, System.Collections.Generic.IEnumerable? tags = null, System.TimeSpan? timeout = default) { } + } +} \ No newline at end of file