diff --git a/raft/raft_test.go b/raft/raft_test.go index 94e19c8e3..480da09ed 100644 --- a/raft/raft_test.go +++ b/raft/raft_test.go @@ -102,6 +102,50 @@ func TestSingleNodeCommit(t *testing.T) { } } +func TestCannotCommitWithoutNewTermEntry(t *testing.T) { + tt := newNetwork(nil, nil, nil, nil, nil) + tt.send(Message{To: 0, Type: msgHup}) + + // 0 cannot reach 2,3,4 + tt.drop(0, 2, 1.0) + tt.drop(2, 0, 1.0) + + tt.drop(0, 3, 1.0) + tt.drop(3, 0, 1.0) + + tt.drop(0, 4, 1.0) + tt.drop(4, 0, 1.0) + + tt.send(Message{To: 0, Type: msgProp, Data: []byte("some data")}) + tt.send(Message{To: 0, Type: msgProp, Data: []byte("some data")}) + + sm := tt.peers[0].(*stateMachine) + if sm.log.committed != 0 { + t.Errorf("committed = %d, want %d", sm.log.committed, 0) + } + + // network recovery + tt.recover() + + // elect 1 as the new leader with term 2 + tt.send(Message{To: 1, Type: msgHup}) + // send out a heartbeat + tt.send(Message{To: 1, Type: msgBeat}) + + // no log entries from previous term should be committed + sm = tt.peers[1].(*stateMachine) + if sm.log.committed != 0 { + t.Errorf("committed = %d, want %d", sm.log.committed, 0) + } + + // after append a entry from the current term, all entries + // should be committed + tt.send(Message{To: 1, Type: msgProp, Data: []byte("some data")}) + if sm.log.committed != 3 { + t.Errorf("committed = %d, want %d", sm.log.committed, 3) + } +} + func TestDuelingCandidates(t *testing.T) { a := newStateMachine(0, 0) // k, addr are set later c := newStateMachine(0, 0)