125 lines
4.6 KiB
C#
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();
|
|
}
|
|
}
|