Browse Source

raft: add test for findConflict

Xiang Li 11 years ago
parent
commit
90f26e4a56
2 changed files with 46 additions and 0 deletions
  1. 10 0
      raft/log.go
  2. 36 0
      raft/log_test.go

+ 10 - 0
raft/log.go

@@ -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 {

+ 36 - 0
raft/log_test.go

@@ -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