Files
CBDDC/tests/ZB.MOM.WW.CBDDC.Hosting.Tests/CBDDCHostingExtensionsTests.cs

125 lines
4.6 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using ZB.MOM.WW.CBDDC.Hosting.Configuration;
using ZB.MOM.WW.CBDDC.Hosting.HostedServices;
using ZB.MOM.WW.CBDDC.Hosting.Services;
using ZB.MOM.WW.CBDDC.Network;
namespace ZB.MOM.WW.CBDDC.Hosting.Tests;
public class CBDDCHostingExtensionsTests
{
/// <summary>
/// Verifies that adding CBDDC hosting throws when the service collection is null.
/// </summary>
[Fact]
public void AddCBDDCHosting_WithNullServices_ThrowsArgumentNullException()
{
Should.Throw<ArgumentNullException>(() =>
CBDDCHostingExtensions.AddCBDDCHosting(null!, _ => { }));
}
/// <summary>
/// Verifies that adding CBDDC hosting throws when the configuration delegate is null.
/// </summary>
[Fact]
public void AddCBDDCHosting_WithNullConfigure_ThrowsArgumentNullException()
{
var services = new ServiceCollection();
Should.Throw<ArgumentNullException>(() => services.AddCBDDCHosting(null!));
}
/// <summary>
/// Verifies that single-cluster hosting registers expected services and configured options.
/// </summary>
[Fact]
public void AddCBDDCHostingSingleCluster_RegistersExpectedServicesAndOptions()
{
var services = new ServiceCollection();
services.AddCBDDCHostingSingleCluster(options =>
{
options.NodeId = "node-1";
options.TcpPort = 5055;
options.PeerConfirmationLagThresholdMs = 45_000;
options.PeerConfirmationCriticalLagThresholdMs = 180_000;
});
var optionsDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(CBDDCHostingOptions));
optionsDescriptor.ShouldNotBeNull();
var options = optionsDescriptor.ImplementationInstance.ShouldBeOfType<CBDDCHostingOptions>();
options.Cluster.NodeId.ShouldBe("node-1");
options.Cluster.TcpPort.ShouldBe(5055);
options.Cluster.PeerConfirmationLagThresholdMs.ShouldBe(45_000);
options.Cluster.PeerConfirmationCriticalLagThresholdMs.ShouldBe(180_000);
ShouldContainService<IDiscoveryService, NoOpDiscoveryService>(services);
ShouldContainService<ISyncOrchestrator, SyncOrchestrator>(services);
ShouldContainHostedService<TcpSyncServerHostedService>(services);
ShouldContainHostedService<DiscoveryServiceHostedService>(services);
using var provider = services.BuildServiceProvider();
var healthChecks = provider.GetRequiredService<IOptions<HealthCheckServiceOptions>>().Value;
var registration = healthChecks.Registrations.SingleOrDefault(r => r.Name == "cbddc");
registration.ShouldNotBeNull();
registration.FailureStatus.ShouldBe(HealthStatus.Unhealthy);
registration.Tags.ShouldContain("db");
registration.Tags.ShouldContain("ready");
}
/// <summary>
/// Verifies that single-cluster hosting uses default options when no configuration delegate is provided.
/// </summary>
[Fact]
public void AddCBDDCHostingSingleCluster_WithNullConfigure_UsesDefaults()
{
var services = new ServiceCollection();
services.AddCBDDCHostingSingleCluster();
var optionsDescriptor = services.SingleOrDefault(d => d.ServiceType == typeof(CBDDCHostingOptions));
optionsDescriptor.ShouldNotBeNull();
var options = optionsDescriptor.ImplementationInstance.ShouldBeOfType<CBDDCHostingOptions>();
options.Cluster.ShouldNotBeNull();
}
/// <summary>
/// Verifies that health check registration is skipped when health checks are disabled.
/// </summary>
[Fact]
public void AddCBDDCHosting_WithHealthChecksDisabled_DoesNotRegisterCBDDCHealthCheck()
{
var services = new ServiceCollection();
services.AddCBDDCHosting(options =>
{
options.EnableHealthChecks = false;
});
services.Any(d => d.ServiceType == typeof(IConfigureOptions<HealthCheckServiceOptions>))
.ShouldBeFalse();
}
private static void ShouldContainService<TService, TImplementation>(IServiceCollection services)
{
services.Any(d =>
d.ServiceType == typeof(TService) &&
d.ImplementationType == typeof(TImplementation))
.ShouldBeTrue();
}
private static void ShouldContainHostedService<THostedService>(IServiceCollection services)
{
services.Any(d =>
d.ServiceType == typeof(IHostedService) &&
d.ImplementationType == typeof(THostedService))
.ShouldBeTrue();
}
}