|
@@ -1405,6 +1405,75 @@ func TestNonPromotableVoterWithCheckQuorum(t *testing.T) {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func TestReadIndexWithCheckQuorum(t *testing.T) {
|
|
|
|
|
+ a := newTestRaft(1, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+ b := newTestRaft(2, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+ c := newTestRaft(3, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+
|
|
|
|
|
+ a.checkQuorum = true
|
|
|
|
|
+ b.checkQuorum = true
|
|
|
|
|
+ c.checkQuorum = true
|
|
|
|
|
+
|
|
|
|
|
+ nt := newNetwork(a, b, c)
|
|
|
|
|
+ for i := 0; i < b.electionTimeout; i++ {
|
|
|
|
|
+ b.tick()
|
|
|
|
|
+ }
|
|
|
|
|
+ nt.send(pb.Message{From: 1, To: 1, Type: pb.MsgHup})
|
|
|
|
|
+
|
|
|
|
|
+ if a.state != StateLeader {
|
|
|
|
|
+ t.Fatalf("state = %s, want %s", a.state, StateLeader)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ tests := []struct {
|
|
|
|
|
+ sm *raft
|
|
|
|
|
+ proposals int
|
|
|
|
|
+ wri uint64
|
|
|
|
|
+ wctx []byte
|
|
|
|
|
+ }{
|
|
|
|
|
+ {b, 10, 11, []byte("ctx1")},
|
|
|
|
|
+ {c, 10, 21, []byte("ctx2")},
|
|
|
|
|
+ {b, 10, 31, []byte("ctx3")},
|
|
|
|
|
+ {c, 10, 41, []byte("ctx4")},
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for _, tt := range tests {
|
|
|
|
|
+ for j := 0; j < tt.proposals; j++ {
|
|
|
|
|
+ nt.send(pb.Message{From: 1, To: 1, Type: pb.MsgProp, Entries: []pb.Entry{{}}})
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ nt.send(pb.Message{From: tt.sm.id, To: tt.sm.id, Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: tt.wctx}}})
|
|
|
|
|
+
|
|
|
|
|
+ r := tt.sm
|
|
|
|
|
+ if r.readState.Index != tt.wri {
|
|
|
|
|
+ t.Errorf("readIndex = %d, want %d", r.readState.Index, tt.wri)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if !bytes.Equal(r.readState.RequestCtx, tt.wctx) {
|
|
|
|
|
+ t.Errorf("requestCtx = %v, want %v", r.readState.RequestCtx, tt.wctx)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func TestReadIndexWithoutCheckQuorum(t *testing.T) {
|
|
|
|
|
+ a := newTestRaft(1, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+ b := newTestRaft(2, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+ c := newTestRaft(3, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
|
|
|
|
+
|
|
|
|
|
+ nt := newNetwork(a, b, c)
|
|
|
|
|
+ nt.send(pb.Message{From: 1, To: 1, Type: pb.MsgHup})
|
|
|
|
|
+
|
|
|
|
|
+ ctx := []byte("ctx1")
|
|
|
|
|
+ nt.send(pb.Message{From: 2, To: 2, Type: pb.MsgReadIndex, Entries: []pb.Entry{{Data: ctx}}})
|
|
|
|
|
+
|
|
|
|
|
+ if b.readState.Index != None {
|
|
|
|
|
+ t.Errorf("readIndex = %d, want %d", b.readState.Index, None)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if !bytes.Equal(b.readState.RequestCtx, ctx) {
|
|
|
|
|
+ t.Errorf("requestCtx = %v, want %v", b.readState.RequestCtx, ctx)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func TestLeaderAppResp(t *testing.T) {
|
|
func TestLeaderAppResp(t *testing.T) {
|
|
|
// initial progress: match = 0; next = 3
|
|
// initial progress: match = 0; next = 3
|
|
|
tests := []struct {
|
|
tests := []struct {
|