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 { /// Verifies that non-Up member statuses return a service level of zero. /// The Akka cluster member status to test. [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); } /// Verifies that a fully healthy non-leader member returns a service level of 240. [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); } /// Verifies that a fully healthy role leader returns a service level of 250. [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); } /// Verifies that a database reachable but stale returns a service level of 200. [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); } /// Verifies that an unreachable and stale database returns a service level of 100. [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); } /// Verifies that an OPC UA probe failure on a non-stale database returns zero. [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); } /// Verifies that a Joining member status is treated like Up for service level grading. [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); } }