public async Task CandidateShouldApplyLogsToFsm() { var currentState = new CurrentState(Guid.NewGuid().ToString(), 0, default(string), 0, 0, default(string)); var fsm = new InMemoryStateMachine(); var candidate = new Candidate(currentState, fsm, _peers, _log, _random, _node, _settings, _rules, _loggerFactory.Object); var log = new LogEntry(new FakeCommand("test"), typeof(string), 1); var appendEntries = new AppendEntriesBuilder() .WithTerm(1) .WithPreviousLogTerm(1) .WithEntry(log) .WithPreviousLogIndex(1) .WithLeaderCommitIndex(1) .Build(); await _log.Apply(log); var appendEntriesResponse = await candidate.Handle(appendEntries); appendEntriesResponse.Success.ShouldBeTrue(); candidate.CurrentState.CurrentTerm.ShouldBe(1); candidate.CurrentState.LastApplied.ShouldBe(1); fsm.HandledLogEntries.ShouldBe(1); var node = (NothingNode)_node; node.BecomeFollowerCount.ShouldBe(1); }
public void CandidateShouldApplyLogsToFsm() { var currentState = new CurrentState(Guid.NewGuid(), 0, default(Guid), 0, 0, default(Guid)); var fsm = new Rafty.FiniteStateMachine.InMemoryStateMachine(); var candidate = new Candidate(currentState, fsm, _peers, _log, _random, _node, _settings, _rules); var log = new LogEntry(new FakeCommand("test"), typeof(string), 1); var appendEntries = new AppendEntriesBuilder() .WithTerm(1) .WithPreviousLogTerm(1) .WithEntry(log) .WithPreviousLogIndex(1) .WithLeaderCommitIndex(1) .Build(); //assume node has added the log.. _log.Apply(log); var appendEntriesResponse = candidate.Handle(appendEntries); candidate.CurrentState.CurrentTerm.ShouldBe(1); candidate.CurrentState.LastApplied.ShouldBe(1); fsm.ExposedForTesting.ShouldBe(1); var node = (NothingNode)_node; node.BecomeFollowerCount.ShouldBe(1); }
public void ShouldReplyFalseIfRpcTermLessThanCurrentTerm() { _currentState = new CurrentState(Guid.NewGuid(), 1, default(Guid), 0, 0, default(Guid)); var appendEntriesRpc = new AppendEntriesBuilder().WithTerm(0).Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers); var appendEntriesResponse = follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(false); appendEntriesResponse.Term.ShouldBe(1); }
public async Task ShouldReplyFalseIfRpcTermLessThanCurrentTerm() { _currentState = new CurrentState(Guid.NewGuid().ToString(), 1, default(string), 0, 0, default(string)); var appendEntriesRpc = new AppendEntriesBuilder().WithTerm(0).Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers, _loggerFactory.Object); var appendEntriesResponse = await follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(false); appendEntriesResponse.Term.ShouldBe(1); }
public void ShouldReplyFalseIfLogDoesntContainEntryAtPreviousLogIndexWhoseTermMatchesRpcPrevLogTerm() { _currentState = new CurrentState(Guid.NewGuid(), 2, default(Guid), 0, 0, default(Guid)); _log.Apply(new LogEntry(new FakeCommand(""), typeof(string), 2)); var appendEntriesRpc = new AppendEntriesBuilder().WithTerm(2).WithPreviousLogIndex(1).WithPreviousLogTerm(1).Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers); var appendEntriesResponse = follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(false); appendEntriesResponse.Term.ShouldBe(2); }
public async Task FollowerShouldAppendNewEntries() { _currentState = new CurrentState(Guid.NewGuid().ToString(), 0, default(string), 0, 0, default(string)); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers, _loggerFactory.Object); var logEntry = new LogEntry(new FakeCommand(), typeof(FakeCommand), 1); var appendEntries = new AppendEntriesBuilder().WithTerm(1).WithEntry(logEntry).Build(); var response = await follower.Handle(appendEntries); response.Success.ShouldBeTrue(); response.Term.ShouldBe(1); var inMemoryLog = (InMemoryLog)_log; inMemoryLog.ExposedForTesting.Count.ShouldBe(1); }
public void ShouldDeleteExistingEntryIfItConflictsWithNewOne() { _currentState = new CurrentState(Guid.NewGuid(), 1, default(Guid), 2, 0, default(Guid)); _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1)); _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 1"), typeof(string), 1)); _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 2"), typeof(string), 1)); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(new LogEntry(new FakeCommand("term 2 commit index 2"), typeof(string), 2)) .WithTerm(2) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers); var appendEntriesResponse = follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(true); appendEntriesResponse.Term.ShouldBe(2); }
public void FollowerShouldSetCommitIndexIfLeaderCommitGreaterThanCommitIndex() { _currentState = new CurrentState(Guid.NewGuid(), 1, default(Guid), 0, 0, default(Guid)); var log = new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1); _log.Apply(log); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(log) .WithTerm(1) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .WithLeaderCommitIndex(1) .Build(); //assume node has applied log.. var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers); var appendEntriesResponse = follower.Handle(appendEntriesRpc); follower.CurrentState.CommitIndex.ShouldBe(1); }
public void ShouldAppendAnyEntriesNotInTheLog() { _currentState = new CurrentState(Guid.NewGuid(), 1, default(Guid), 0, 0, default(Guid)); _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1)); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(new LogEntry(new FakeCommand("term 1 commit index 1"), typeof(string), 1)) .WithTerm(1) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .WithLeaderId(Guid.NewGuid()) .Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers); var appendEntriesResponse = follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(true); appendEntriesResponse.Term.ShouldBe(1); _log.GetTermAtIndex(1).ShouldBe(1); follower.CurrentState.LeaderId.ShouldBe(appendEntriesRpc.LeaderId); }
public async Task CandidateShouldNotAppendDuplicateEntry() { _node = new NothingNode(); _currentState = new CurrentState(Guid.NewGuid().ToString(), 0, default(string), 0, 0, default(string)); var candidate = new Candidate(_currentState, _fsm, _peers, _log, _random, _node, _settings, _rules, _loggerFactory.Object); var logEntry = new LogEntry(new FakeCommand(), typeof(FakeCommand), 1); var appendEntries = new AppendEntriesBuilder().WithPreviousLogIndex(1).WithPreviousLogTerm(1).WithTerm(1).WithEntry(logEntry).WithTerm(1).WithLeaderCommitIndex(1).Build(); var response = await candidate.Handle(appendEntries); response.Success.ShouldBeTrue(); response.Term.ShouldBe(1); response = await candidate.Handle(appendEntries); response.Success.ShouldBeTrue(); response.Term.ShouldBe(1); var inMemoryLog = (InMemoryLog)_log; inMemoryLog.ExposedForTesting.Count.ShouldBe(1); }
public async Task FollowerShouldSetCommitIndexIfLeaderCommitGreaterThanCommitIndex() { _currentState = new CurrentState(Guid.NewGuid().ToString(), 1, default(string), 0, 0, default(string)); var log = new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1); await _log.Apply(log); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(log) .WithTerm(1) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .WithLeaderCommitIndex(1) .Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers, _loggerFactory.Object); var response = await follower.Handle(appendEntriesRpc); response.Success.ShouldBeTrue(); follower.CurrentState.CommitIndex.ShouldBe(1); }
public void LeaderShouldSetCommitIndexIfLeaderCommitGreaterThanCommitIndex() { _currentState = new CurrentState(Guid.NewGuid(), 0, default(Guid), 0, 0, default(Guid)); //assume log applied by node? var log = new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1); _log.Apply(log); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(log) .WithTerm(1) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .WithLeaderCommitIndex(1) .WithLeaderId(Guid.NewGuid()) .Build(); var leader = new Leader(_currentState, _fsm, (s) => _peers, _log, _node, _settings, _rules); var state = leader.Handle(appendEntriesRpc); leader.CurrentState.CommitIndex.ShouldBe(1); leader.CurrentState.LeaderId.ShouldBe(appendEntriesRpc.LeaderId); }
public async Task CandidateShouldSetCommitIndexIfLeaderCommitGreaterThanCommitIndex() { _currentState = new CurrentState(Guid.NewGuid().ToString(), 0, default(string), 0, 0, default(string)); //assume log applied by node? var log = new LogEntry(new FakeCommand("term 1 commit index 0"), typeof(string), 1); await _log.Apply(log); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(log) .WithTerm(1) .WithPreviousLogIndex(1) .WithPreviousLogTerm(1) .WithLeaderCommitIndex(1) .WithLeaderId(Guid.NewGuid().ToString()) .Build(); var candidate = new Candidate(_currentState, _fsm, _peers, _log, _random, _node, _settings, _rules); var appendEntriesResponse = await candidate.Handle(appendEntriesRpc); candidate.CurrentState.CommitIndex.ShouldBe(1); candidate.CurrentState.LeaderId.ShouldBe(appendEntriesRpc.LeaderId); }
public async Task LeaderShouldApplyLogsToFsm() { var currentState = new CurrentState(Guid.NewGuid().ToString(), 0, default(string), 0, 0, default(string)); var fsm = new Rafty.FiniteStateMachine.InMemoryStateMachine(); var leader = new Leader(currentState, fsm, (s) => _peers, _log, _node, _settings, _rules); var log = new LogEntry(new FakeCommand("test"), typeof(string), 1); var appendEntries = new AppendEntriesBuilder() .WithTerm(1) .WithPreviousLogTerm(1) .WithEntry(log) .WithPreviousLogIndex(1) .WithLeaderCommitIndex(1) .Build(); //assume node has added the log.. await _log.Apply(log); var appendEntriesResponse = leader.Handle(appendEntries); leader.CurrentState.CurrentTerm.ShouldBe(1); leader.CurrentState.LastApplied.ShouldBe(1); fsm.HandledLogEntries.ShouldBe(1); }
public async Task ShouldDeleteExistingEntryIfItConflictsWithNewOne() { _currentState = new CurrentState(Guid.NewGuid().ToString(), 1, default(string), 2, 0, default(string)); await _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 1"), typeof(string), 1)); await _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 2"), typeof(string), 1)); await _log.Apply(new LogEntry(new FakeCommand("term 1 commit index 3"), typeof(string), 1)); var appendEntriesRpc = new AppendEntriesBuilder() .WithEntry(new LogEntry(new FakeCommand("term 2 commit index 3"), typeof(string), 2)) .WithTerm(2) .WithPreviousLogIndex(2) .WithPreviousLogTerm(1) .WithLeaderCommitIndex(3) .Build(); var follower = new Follower(_currentState, _fsm, _log, _random, _node, _settings, _rules, _peers, _loggerFactory.Object); var appendEntriesResponse = await follower.Handle(appendEntriesRpc); appendEntriesResponse.Success.ShouldBe(true); appendEntriesResponse.Term.ShouldBe(2); }