using Akka.Cluster; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.ControlPlane.Redundancy; namespace ZB.MOM.WW.OtOpcUa.ControlPlane.Tests; public sealed class ServiceLevelCalculatorTests { [Theory] [InlineData(MemberStatus.Down)] [InlineData(MemberStatus.Removed)] [InlineData(MemberStatus.Exiting)] [InlineData(MemberStatus.Leaving)] public void NotUp_returns_zero(MemberStatus status) { var sl = ServiceLevelCalculator.Compute(new(status, DbReachable: true, OpcUaProbeOk: true, Stale: false, IsDriverRoleLeader: true)); sl.ShouldBe((byte)0); } [Fact] public void Fully_healthy_non_leader_returns_240() { var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Up, DbReachable: true, OpcUaProbeOk: true, Stale: false, IsDriverRoleLeader: false)); sl.ShouldBe((byte)240); } [Fact] public void Fully_healthy_role_leader_returns_250() { var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Up, DbReachable: true, OpcUaProbeOk: true, Stale: false, IsDriverRoleLeader: true)); sl.ShouldBe((byte)250); } [Fact] public void Db_reachable_but_stale_returns_200() { var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Up, DbReachable: true, OpcUaProbeOk: true, Stale: true, IsDriverRoleLeader: false)); sl.ShouldBe((byte)200); } [Fact] public void Db_unreachable_and_stale_returns_100() { var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Up, DbReachable: false, OpcUaProbeOk: false, Stale: true, IsDriverRoleLeader: false)); sl.ShouldBe((byte)100); } [Fact] public void Opcua_probe_fail_when_not_stale_returns_zero() { // (DbReachable=true, OpcUaProbeOk=false, Stale=false) falls through to the catch-all 0. var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Up, DbReachable: true, OpcUaProbeOk: false, Stale: false, IsDriverRoleLeader: false)); sl.ShouldBe((byte)0); } [Fact] public void Joining_member_is_treated_like_Up_for_grading() { var sl = ServiceLevelCalculator.Compute(new(MemberStatus.Joining, DbReachable: true, OpcUaProbeOk: true, Stale: false, IsDriverRoleLeader: false)); sl.ShouldBe((byte)240); } }