func TestConsensusModule_AppendCommand_Follower(t *testing.T) { cm, _ := setupConsensusModuleR2(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) defer cm.Stop() // pre check iole, err := cm.passiveConsensusModule.LogRO.GetIndexOfLastEntry() if err != nil { t.Fatal() } if iole != 10 { t.Fatal() } _, err = cm.AppendCommand(testhelpers.DummyCommand(1101)) if err != ErrNotLeader { t.Fatal() } if cm.IsStopped() { t.Error() } iole, err = cm.passiveConsensusModule.LogRO.GetIndexOfLastEntry() if err != nil { t.Fatal() } if iole != 10 { t.Fatal() } }
func TestConsensusModule_AppendCommand_Follower_StoppedCM(t *testing.T) { cm, _ := setupConsensusModuleR2(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) cm.Stop() _, err := cm.AppendCommand(testhelpers.DummyCommand(1101)) if err != ErrStopped { t.Fatal(err) } }
func TestCM_SOLO_Leader_TickAdvancesCommitIndexIfPossible(t *testing.T) { var err error mcm, mrs := testSetupMCM_SOLO_Leader_WithTerms(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) serverTerm := mcm.pcm.RaftPersistentState.GetCurrentTerm() // pre checks if serverTerm != 8 { t.Fatal() } if mcm.pcm.GetCommitIndex() != 0 { t.Fatal() } mrs.CheckSentRpcs(t, map[ServerId]interface{}{}) mrs.ClearSentRpcs() // tick should try to advance commitIndex but nothing should happen err = mcm.Tick() if err != nil { t.Fatal(err) } if mcm.pcm.GetCommitIndex() != 0 { t.Fatal() } mrs.CheckSentRpcs(t, map[ServerId]interface{}{}) mrs.ClearSentRpcs() // let's make some new log entries ioleAC, err := mcm.pcm.AppendCommand(testhelpers.DummyCommand(11)) if err != nil || ioleAC != 11 { t.Fatal() } ioleAC, err = mcm.pcm.AppendCommand(testhelpers.DummyCommand(12)) if err != nil || ioleAC != 12 { t.Fatal() } // commitIndex does not advance immediately if mcm.pcm.GetCommitIndex() != 0 { t.Fatal() } // tick will advance commitIndex to the highest match possible err = mcm.Tick() if err != nil { t.Fatal(err) } if mcm.pcm.GetCommitIndex() != 12 { t.Fatal(mcm.pcm.GetCommitIndex()) } mrs.CheckSentRpcs(t, map[ServerId]interface{}{}) mrs.ClearSentRpcs() }
func testSetupMCM_FollowerTerm8_Figure7LeaderLine(t *testing.T) (*managedConsensusModule, *testhelpers.MockRpcSender) { mcm, mrs := testSetupMCM_Follower_WithTerms(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) serverTerm := mcm.pcm.RaftPersistentState.GetCurrentTerm() // sanity check if serverTerm != 7 { t.Fatal(serverTerm) } // pretend server was pushed to term 8 err := mcm.pcm.RaftPersistentState.SetCurrentTerm(8) if err != nil { t.Fatal(err) } return mcm, mrs }
func testSetupMCM_FollowerThatVotedForS2_Figure7LeaderLine( t *testing.T, ) (*managedConsensusModule, *testhelpers.MockRpcSender) { mcm, mrs := testSetupMCM_Follower_WithTerms(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) // sanity check if mcm.pcm.RaftPersistentState.GetVotedFor() != "" { t.Fatal() } // pretend server voted err := mcm.pcm.RaftPersistentState.SetVotedFor("s2") if err != nil { t.Fatal(err) } return mcm, mrs }
func testSetupMCM_Leader_Figure7LeaderLine_WithUpToDatePeers(t *testing.T) (*managedConsensusModule, *testhelpers.MockRpcSender) { mcm, mrs := testSetupMCM_Leader_WithTerms(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) // sanity check - before expectedNextIndex := map[ServerId]LogIndex{"s2": 11, "s3": 11, "s4": 11, "s5": 11} if !reflect.DeepEqual(mcm.pcm.LeaderVolatileState.NextIndex, expectedNextIndex) { t.Fatal() } expectedMatchIndex := map[ServerId]LogIndex{"s2": 0, "s3": 0, "s4": 0, "s5": 0} if !reflect.DeepEqual(mcm.pcm.LeaderVolatileState.MatchIndex, expectedMatchIndex) { t.Fatal() } // pretend peers caught up! lastLogIndex, err := mcm.pcm.LogRO.GetIndexOfLastEntry() if err != nil { t.Fatal() } err = mcm.pcm.ClusterInfo.ForEachPeer( func(serverId ServerId) error { err := mcm.pcm.LeaderVolatileState.SetMatchIndexAndNextIndex(serverId, lastLogIndex) if err != nil { return err } return nil }, ) if err != nil { t.Fatal() } // after check expectedNextIndex = map[ServerId]LogIndex{"s2": 11, "s3": 11, "s4": 11, "s5": 11} if !reflect.DeepEqual(mcm.pcm.LeaderVolatileState.NextIndex, expectedNextIndex) { t.Fatal() } expectedMatchIndex = map[ServerId]LogIndex{"s2": 10, "s3": 10, "s4": 10, "s5": 10} if !reflect.DeepEqual(mcm.pcm.LeaderVolatileState.MatchIndex, expectedMatchIndex) { t.Fatal() } return mcm, mrs }
func TestConsensusModule_AppendCommand_Leader(t *testing.T) { cm, mrs := setupConsensusModuleR2(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) defer cm.Stop() testConsensusModule_RpcReplyCallback_AndBecomeLeader(t, cm, mrs) // pre check iole, err := cm.passiveConsensusModule.LogRO.GetIndexOfLastEntry() if err != nil { t.Fatal() } if iole != 10 { t.Fatal() } ioleAC, err := cm.AppendCommand(testhelpers.DummyCommand(1101)) if cm.IsStopped() { t.Error() } if err != nil { t.Fatal() } if ioleAC != 11 { t.Fatal() } iole, err = cm.passiveConsensusModule.LogRO.GetIndexOfLastEntry() if err != nil { t.Fatal() } if iole != 11 { t.Fatal() } le := testhelpers.TestHelper_GetLogEntryAtIndex(cm.passiveConsensusModule.LogRO, 11) if !reflect.DeepEqual(le, LogEntry{8, Command("c1101")}) { t.Fatal(le) } }
// Make an InMemoryLog with 10 entries with terms as shown in Figure 7, leader line. // Commands will be Command("c1"), Command("c2"), etc. func TestUtil_NewInMemoryLog_WithFigure7LeaderLine() *InMemoryLog { figure7LeaderLine := testdata.TestUtil_MakeFigure7LeaderLineTerms() return TestUtil_NewInMemoryLog_WithTerms(figure7LeaderLine) }
func testSetupMCM_Leader_Figure7LeaderLine(t *testing.T) (*managedConsensusModule, *testhelpers.MockRpcSender) { return testSetupMCM_Leader_WithTerms(t, testdata.TestUtil_MakeFigure7LeaderLineTerms()) }