raft: add test for findConflict

release-2.0
Xiang Li 2014-10-25 18:49:49 -07:00
parent 2b9cabcbcd
commit 90f26e4a56
2 changed files with 46 additions and 0 deletions

View File

@ -83,6 +83,16 @@ func (l *raftLog) append(after uint64, ents ...pb.Entry) uint64 {
return l.lastIndex()
}
// findConflict finds the index of the conflict.
// It returns the the first pair of confilcting entries between the existing
// entries and the given entries, if there is any.
// If there is no conflicting entries, and the existing entries contains
// all the given entries, zero will be returned.
// If there is no conflicting entries, but the given entries contains new
// entries, the index of the first new entry will be returned.
// Conflicting entries has the same index but different term.
// The first given entry MUST have the index equal to from.
// The index of the given entries MUST be continously increasing.
func (l *raftLog) findConflict(from uint64, ents []pb.Entry) uint64 {
for i, ne := range ents {
if oe := l.at(from + uint64(i)); oe == nil || oe.Term != ne.Term {

View File

@ -23,6 +23,42 @@ import (
pb "github.com/coreos/etcd/raft/raftpb"
)
func TestFindConflict(t *testing.T) {
previousEnts := []pb.Entry{{Term: 1}, {Term: 2}, {Term: 3}}
tests := []struct {
from uint64
ents []pb.Entry
wconflict uint64
}{
// no conflict, empty ent
{1, []pb.Entry{}, 0},
{3, []pb.Entry{}, 0},
// no conflict
{1, []pb.Entry{{Term: 1}, {Term: 2}, {Term: 3}}, 0},
{2, []pb.Entry{{Term: 2}, {Term: 3}}, 0},
{3, []pb.Entry{{Term: 3}}, 0},
// no conflict, but has new entries
{1, []pb.Entry{{Term: 1}, {Term: 2}, {Term: 3}, {Term: 4}, {Term: 4}}, 4},
{2, []pb.Entry{{Term: 2}, {Term: 3}, {Term: 4}, {Term: 4}}, 4},
{3, []pb.Entry{{Term: 3}, {Term: 4}, {Term: 4}}, 4},
{4, []pb.Entry{{Term: 4}, {Term: 4}}, 4},
// conflicts with existing entries
{1, []pb.Entry{{Term: 4}, {Term: 4}}, 1},
{2, []pb.Entry{{Term: 1}, {Term: 4}, {Term: 4}}, 2},
{3, []pb.Entry{{Term: 1}, {Term: 2}, {Term: 4}, {Term: 4}}, 3},
}
for i, tt := range tests {
raftLog := newLog()
raftLog.ents = append(raftLog.ents, previousEnts...)
gconflict := raftLog.findConflict(tt.from, tt.ents)
if gconflict != tt.wconflict {
t.Errorf("#%d: conflict = %d, want %d", i, gconflict, tt.wconflict)
}
}
}
// TestAppend ensures:
// 1. If an existing entry conflicts with a new one (same index
// but different terms), delete the existing entry and all that