public void Test_Backup_Found_Primary()
        {
            StateChanged<InstanceState> stateChanged = null;
            var observer = new MockStateObserver(s => stateChanged = s, Assert.IsNull);
            InstanceState localState;
            ClusterStateMachine machine = CreateClusterStateMachine(observer, NodeRole.Backup, out localState);

            var remoteState = new NodeState { Role = NodeRole.Primary, Status = NodeStatus.Connecting };
            machine.RaiseEvent(localState, machine.PartnerStatusReceived, remoteState);

            Assert.AreEqual("Connecting", stateChanged.Previous.Name);
            Assert.AreEqual("Passive", stateChanged.Current.Name);
        }
        public void Test_LostPartner_During_Any_Should_LogException()
        {
            StateChanged<InstanceState> stateChanged = null;
            var observer = new MockStateObserver(s => stateChanged = s, Assert.IsNull);
            InstanceState localState;
            ClusterException cex = null;
            ClusterStateMachine machine = CreateClusterStateMachine(observer, NodeRole.Primary, out localState,
                ex => cex = ex);

            var remoteState = new NodeState { Role = NodeRole.Backup, Status = NodeStatus.Passive };
            machine.RaiseEvent(localState, machine.PartnerStatusReceived, remoteState);

            machine.RaiseEvent(localState, machine.LostPartner, localState);
            Assert.AreEqual(ClusterFailureReason.LostPartner, cex.Reason);
            Assert.AreEqual("Connecting", stateChanged.Previous.Name);
            Assert.AreEqual("Active", stateChanged.Current.Name);
        }
        public void Test_InvalidTopology()
        {
            StateChanged<InstanceState> stateChanged = null;
            var observer = new MockStateObserver(s => stateChanged = s, Assert.IsNull);
            InstanceState localState;
            ClusterException cex = null;
            ClusterStateMachine machine = CreateClusterStateMachine(observer, NodeRole.Primary, out localState,
                ex => cex = ex);

            var remoteState = new NodeState { Role = NodeRole.Primary, Status = NodeStatus.Connecting };
            machine.RaiseEvent(localState, machine.PartnerStatusReceived, remoteState);
            Assert.AreEqual(ClusterFailureReason.InvalidTopology, cex.Reason);
            Assert.AreEqual("Stopped", stateChanged.Previous.Name);
            Assert.AreEqual("Final", stateChanged.Current.Name);

            machine = CreateClusterStateMachine(observer, NodeRole.Backup, out localState, ex => cex = ex);

            remoteState = new NodeState { Role = NodeRole.Backup, Status = NodeStatus.Connecting };
            machine.RaiseEvent(localState, machine.PartnerStatusReceived, remoteState);
            Assert.AreEqual(ClusterFailureReason.InvalidTopology, cex.Reason);
            Assert.AreEqual("Stopped", stateChanged.Previous.Name);
            Assert.AreEqual("Final", stateChanged.Current.Name);
        }
        public void Test_SplitBrain_Backup()
        {
            StateChanged<InstanceState> stateChanged = null;
            var observer = new MockStateObserver(s => stateChanged = s, Assert.IsNull);
            InstanceState localState;
            ClusterException cex = null;
            ClusterStateMachine machine = CreateClusterStateMachine(observer, NodeRole.Backup, out localState,
                ex => cex = ex);
            var newState = new InstanceState
            {
                CurrentState = machine.Active,
                Role = NodeRole.Backup,
                Status = NodeStatus.Active
            };
            machine.TransitionToState(newState, machine.Active);

            var remoteState = new NodeState { Role = NodeRole.Primary, Status = NodeStatus.Active };
            machine.RaiseEvent(newState, machine.PartnerStatusReceived, remoteState);

            Assert.AreEqual(ClusterFailureReason.SplitBrain, cex.Reason);
            Assert.AreEqual("Stopped", stateChanged.Previous.Name);
            Assert.AreEqual("Final", stateChanged.Current.Name);
        }
 public ClusterException(ClusterFailureReason reason, NodeState localState, NodeState remoteState)
     : this(reason)
 {
     LocalState = localState;
     RemoteState = remoteState;
 }