Skip to content

Commit

Permalink
Merge pull request #25 from StuFrankish/project-organisation
Browse files Browse the repository at this point in the history
Implemented configuration options
  • Loading branch information
StuFrankish authored May 13, 2024
2 parents 7e7d5ad + 073760a commit 771157c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 8 deletions.
37 changes: 35 additions & 2 deletions HealthChecks.UnitTests/TestSuite.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using HealthChecks.Uptime;
using HealthChecks.Uptime.Options;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace HealthChecks.UnitTests;
Expand All @@ -10,13 +11,14 @@ public class TestSuite
{
private readonly DateTime _fixedStartupTime = new(2023, 1, 1);
private readonly StartupTimeHealthCheck _healthCheckWithFixedTime;
private readonly UptimeHealthCheckOptions _healthCheckOptions = new();

/// <summary>
/// Initializes a new instance of the <see cref="TestSuite"/> class.
/// </summary>
public TestSuite()
{
_healthCheckWithFixedTime = new StartupTimeHealthCheck(_fixedStartupTime);
_healthCheckWithFixedTime = new StartupTimeHealthCheck(_fixedStartupTime, _healthCheckOptions);
}

/// <summary>
Expand All @@ -30,7 +32,7 @@ public TestSuite()
public async Task CheckHealthAsync_Should_ReturnHealthy(int hoursOffset)
{
// Arrange
var healthCheck = hoursOffset == 0 ? _healthCheckWithFixedTime : new StartupTimeHealthCheck(DateTime.Now.AddHours(hoursOffset));
var healthCheck = hoursOffset == 0 ? _healthCheckWithFixedTime : new StartupTimeHealthCheck(DateTime.Now.AddHours(hoursOffset), _healthCheckOptions);

// Act
var result = await healthCheck.CheckHealthAsync(new HealthCheckContext());
Expand All @@ -57,4 +59,35 @@ public async Task CheckHealthAsync_Should_ReturnHealthy_WithCustomStartupTime()
Assert.True(data.ContainsKey("Uptime"));
Assert.Equal(_fixedStartupTime.ToString("o"), data["Startup Time"].ToString());
}
/// <summary>
/// Tests the CheckHealthAsync method to ensure it returns a degraded status when DegradedThresholdInSeconds is set.
/// </summary>
/// <param name="hoursOffset">The number of hours offset from the startup time.</param>
/// <returns>A task representing the asynchronous operation.</returns>
[Theory]
[InlineData(0)] // At startup
[InlineData(-1)] // After 1 hour of uptime
public async Task CheckHealthAsync_Should_ReturnDegraded_WhenDegradedThresholdInSecondsIsSet(int hoursOffset)
{
// Arrange
var degradedThresholdInSeconds = 3600; // Set the degraded threshold to 1 hour
_healthCheckOptions.DegradedThresholdInSeconds = degradedThresholdInSeconds;

var healthCheck = new StartupTimeHealthCheck(DateTime.Now.AddHours(hoursOffset), _healthCheckOptions);

// Act
var result = await healthCheck.CheckHealthAsync(new HealthCheckContext());

// Assert
if (hoursOffset == 0)
{
Assert.Equal(HealthStatus.Degraded, result.Status);
Assert.Contains("Application is experiencing degraded service.", result.Description);
}
else
{
Assert.Equal(HealthStatus.Healthy, result.Status);
Assert.Contains("Application has been running without issues.", result.Description);
}
}
}
1 change: 1 addition & 0 deletions HealthChecks.Uptime/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ internal sealed class Language
public const string Data_Uptime = "Uptime";
public const string Data_StartupTime = "Startup Time";
public const string Data_HealthyDescription = "Application has been running without issues.";
public const string Data_DegradedDescription = "Application is experiencing degraded service.";
}
}
22 changes: 20 additions & 2 deletions HealthChecks.Uptime/Extensions/ServiceCollectionExtension.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using HealthChecks.Uptime.Options;
using Microsoft.Extensions.DependencyInjection;

namespace HealthChecks.Uptime;

Expand All @@ -11,7 +12,24 @@ public static class ServiceCollectionExtension
/// <returns>The <see cref="IHealthChecksBuilder"/> with the Uptime health check added.</returns>
public static IHealthChecksBuilder AddUptimeHealthCheck(this IHealthChecksBuilder builder)
{
builder.Services.AddSingleton(implementationInstance: new StartupTimeHealthCheck(DateTime.Now));
builder.Services.AddSingleton(implementationInstance: new StartupTimeHealthCheck(DateTime.Now, options: null));
builder.AddCheck<StartupTimeHealthCheck>(name: Constants.Configuration.DefaultCheckName);

return builder;
}

/// <summary>
/// Adds the Uptime health check to the <see cref="IHealthChecksBuilder"/> with the specified options.
/// </summary>
/// <param name="builder">The <see cref="IHealthChecksBuilder"/> to add the health check to.</param>
/// <param name="options">The options for the Uptime health check.</param>
/// <returns>The <see cref="IHealthChecksBuilder"/> with the Uptime health check added.</returns>
public static IHealthChecksBuilder AddUptimeHealthCheck(this IHealthChecksBuilder builder, Action<UptimeHealthCheckOptions>? options)
{
UptimeHealthCheckOptions healthCheckOptions = new();
options?.Invoke(healthCheckOptions);

builder.Services.AddSingleton(implementationInstance: new StartupTimeHealthCheck(DateTime.Now, options: healthCheckOptions));
builder.AddCheck<StartupTimeHealthCheck>(name: Constants.Configuration.DefaultCheckName);

return builder;
Expand Down
49 changes: 46 additions & 3 deletions HealthChecks.Uptime/HealthCheck/StartupTimeHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;
using HealthChecks.Uptime.Options;
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace HealthChecks.Uptime;

/// <summary>
/// Initializes a new instance of the <see cref="StartupTimeHealthCheck"/> class.
/// </summary>
/// <param name="startupTime">The startup time of the application.</param>
public sealed class StartupTimeHealthCheck(DateTime startupTime) : IHealthCheck
public sealed class StartupTimeHealthCheck(DateTime startupTime, UptimeHealthCheckOptions? options) : IHealthCheck
{
private readonly DateTime _startupTime = startupTime;
private readonly UptimeHealthCheckOptions _options = options ?? new();

/// <summary>
/// Checks the health of the application's startup time.
Expand All @@ -21,10 +23,51 @@ public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Canc
var uptime = DateTime.Now - _startupTime;
var data = new Dictionary<string, object>
{
// Formats the startup time as a string using the "o" format specifier (ISO 8601 format)
{ Constants.Language.Data_StartupTime, _startupTime.ToString(format: "o") },

// Include the uptime as a string
{ Constants.Language.Data_Uptime, uptime.ToString() }
};

return Task.FromResult(HealthCheckResult.Healthy(description: Constants.Language.Data_HealthyDescription, data));
// Shortcut for when the degraded threshold is not set or is less than 0
if (
_options.DegradedThresholdInSeconds is null ||
_options.DegradedThresholdInSeconds.HasValue && _options.DegradedThresholdInSeconds.Value < 0
)
{
// Create a new HealthCheckResult object with the specified parameters
var shortResult = new HealthCheckResult(
status: HealthStatus.Healthy,
description: Constants.Language.Data_HealthyDescription,
data: data
);

return Task.FromResult(shortResult);
}

// Normal operation
HealthStatus status;
string description;

if (uptime.TotalSeconds < _options.DegradedThresholdInSeconds)
{
status = HealthStatus.Degraded;
description = Constants.Language.Data_DegradedDescription;
}
else
{
status = HealthStatus.Healthy;
description = Constants.Language.Data_HealthyDescription;
}

// Create a new HealthCheckResult object with the specified parameters
var result = new HealthCheckResult(
status: status,
description: description,
data: data
);

return Task.FromResult(result);
}
}
2 changes: 1 addition & 1 deletion HealthChecks.Uptime/HealthChecks.Uptime.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<OutputType>Library</OutputType>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Uptime HealthCheck</Title>
<Version>2.0.4</Version>
<Version>2.0.5</Version>
<Authors>Stu Frankish</Authors>
<Company>Stu Frankish</Company>
<Description>Application uptime Healthcheck extension.</Description>
Expand Down
6 changes: 6 additions & 0 deletions HealthChecks.Uptime/Options/UptimeHealthCheckOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace HealthChecks.Uptime.Options;

public sealed class UptimeHealthCheckOptions
{
public int? DegradedThresholdInSeconds { get; set; }
}

0 comments on commit 771157c

Please sign in to comment.