using StellaOps.Router.Common.Models; using StellaOps.TestKit; namespace StellaOps.Router.Config.Tests; /// /// Unit tests for . /// public sealed class RouterConfigTests { #region Default Values Tests [Trait("Category", TestCategories.Unit)] [Fact] public void Constructor_PayloadLimits_DefaultsToNewInstance() { // Arrange & Act var config = new RouterConfig(); // Assert config.PayloadLimits.Should().NotBeNull(); } [Trait("Category", TestCategories.Unit)] [Fact] public void Constructor_Routing_DefaultsToNewInstance() { // Arrange & Act var config = new RouterConfig(); // Assert config.Routing.Should().NotBeNull(); } [Trait("Category", TestCategories.Unit)] [Fact] public void Constructor_Services_DefaultsToEmptyList() { // Arrange & Act var config = new RouterConfig(); // Assert config.Services.Should().NotBeNull(); config.Services.Should().BeEmpty(); } [Trait("Category", TestCategories.Unit)] [Fact] public void Constructor_StaticInstances_DefaultsToEmptyList() { // Arrange & Act var config = new RouterConfig(); // Assert config.StaticInstances.Should().NotBeNull(); config.StaticInstances.Should().BeEmpty(); } #endregion #region PayloadLimits Tests [Trait("Category", TestCategories.Unit)] [Fact] public void PayloadLimits_HasDefaultValues() { // Arrange & Act var config = new RouterConfig(); // Assert config.PayloadLimits.MaxRequestBytesPerCall.Should().Be(10 * 1024 * 1024); // 10 MB config.PayloadLimits.MaxRequestBytesPerConnection.Should().Be(100 * 1024 * 1024); // 100 MB config.PayloadLimits.MaxAggregateInflightBytes.Should().Be(1024 * 1024 * 1024); // 1 GB } [Trait("Category", TestCategories.Unit)] [Fact] public void PayloadLimits_CanBeSet() { // Arrange var config = new RouterConfig(); // Act config.PayloadLimits = new PayloadLimits { MaxRequestBytesPerCall = 5 * 1024 * 1024, MaxRequestBytesPerConnection = 50 * 1024 * 1024, MaxAggregateInflightBytes = 500 * 1024 * 1024 }; // Assert config.PayloadLimits.MaxRequestBytesPerCall.Should().Be(5 * 1024 * 1024); config.PayloadLimits.MaxRequestBytesPerConnection.Should().Be(50 * 1024 * 1024); config.PayloadLimits.MaxAggregateInflightBytes.Should().Be(500 * 1024 * 1024); } #endregion #region Routing Tests [Trait("Category", TestCategories.Unit)] [Fact] public void Routing_HasDefaultValues() { // Arrange & Act var config = new RouterConfig(); // Assert config.Routing.LocalRegion.Should().Be("default"); config.Routing.TieBreaker.Should().Be(TieBreakerStrategy.RoundRobin); config.Routing.PreferLocalRegion.Should().BeTrue(); config.Routing.DefaultTimeout.Should().Be(TimeSpan.FromSeconds(30)); } [Trait("Category", TestCategories.Unit)] [Fact] public void Routing_CanBeSet() { // Arrange var config = new RouterConfig(); // Act config.Routing = new RoutingOptions { LocalRegion = "us-east-1", TieBreaker = TieBreakerStrategy.LeastLoaded, PreferLocalRegion = false, DefaultTimeout = TimeSpan.FromMinutes(2), NeighborRegions = ["us-west-1", "eu-west-1"] }; // Assert config.Routing.LocalRegion.Should().Be("us-east-1"); config.Routing.TieBreaker.Should().Be(TieBreakerStrategy.LeastLoaded); config.Routing.PreferLocalRegion.Should().BeFalse(); config.Routing.DefaultTimeout.Should().Be(TimeSpan.FromMinutes(2)); config.Routing.NeighborRegions.Should().HaveCount(2); } #endregion #region Services Tests [Trait("Category", TestCategories.Unit)] [Fact] public void Services_CanAddServices() { // Arrange var config = new RouterConfig(); // Act config.Services.Add(new ServiceConfig { ServiceName = "service-a" }); config.Services.Add(new ServiceConfig { ServiceName = "service-b" }); // Assert config.Services.Should().HaveCount(2); config.Services[0].ServiceName.Should().Be("service-a"); config.Services[1].ServiceName.Should().Be("service-b"); } [Trait("Category", TestCategories.Unit)] [Fact] public void Services_CanBeInitialized() { // Arrange & Act var config = new RouterConfig { Services = [ new ServiceConfig { ServiceName = "auth" }, new ServiceConfig { ServiceName = "users" }, new ServiceConfig { ServiceName = "orders" } ] }; // Assert config.Services.Should().HaveCount(3); } #endregion #region StaticInstances Tests [Trait("Category", TestCategories.Unit)] [Fact] public void StaticInstances_CanAddInstances() { // Arrange var config = new RouterConfig(); // Act config.StaticInstances.Add(new StaticInstanceConfig { ServiceName = "legacy-service", Version = "1.0", Host = "legacy.internal", Port = 9000 }); // Assert config.StaticInstances.Should().HaveCount(1); config.StaticInstances[0].ServiceName.Should().Be("legacy-service"); } [Trait("Category", TestCategories.Unit)] [Fact] public void StaticInstances_CanBeInitialized() { // Arrange & Act var config = new RouterConfig { StaticInstances = [ new StaticInstanceConfig { ServiceName = "db-proxy", Version = "2.0", Host = "db-proxy-1.internal", Port = 5432 }, new StaticInstanceConfig { ServiceName = "db-proxy", Version = "2.0", Host = "db-proxy-2.internal", Port = 5432 } ] }; // Assert config.StaticInstances.Should().HaveCount(2); } #endregion #region Complete Configuration Tests [Trait("Category", TestCategories.Unit)] [Fact] public void CompleteConfiguration_Works() { // Arrange & Act var config = new RouterConfig { PayloadLimits = new PayloadLimits { MaxRequestBytesPerCall = 1024 * 1024, MaxRequestBytesPerConnection = 10 * 1024 * 1024, MaxAggregateInflightBytes = 100 * 1024 * 1024 }, Routing = new RoutingOptions { LocalRegion = "us-east-1", NeighborRegions = ["us-west-1"], TieBreaker = TieBreakerStrategy.ConsistentHash, PreferLocalRegion = true, DefaultTimeout = TimeSpan.FromSeconds(60) }, Services = [ new ServiceConfig { ServiceName = "api-gateway", DefaultVersion = "1.0.0", Endpoints = [ new EndpointConfig { Method = "GET", Path = "/health" } ] } ], StaticInstances = [ new StaticInstanceConfig { ServiceName = "api-gateway", Version = "1.0.0", Host = "api-1.internal", Port = 8080, Weight = 100 } ] }; // Assert config.PayloadLimits.MaxRequestBytesPerCall.Should().Be(1024 * 1024); config.Routing.LocalRegion.Should().Be("us-east-1"); config.Services.Should().HaveCount(1); config.StaticInstances.Should().HaveCount(1); } #endregion }