Browse Source

raft: test case to check the duplicate add node propose

Vincent Lee 9 years ago
parent
commit
16e3ab0f11
1 changed files with 54 additions and 0 deletions
  1. 54 0
      raft/node_test.go

+ 54 - 0
raft/node_test.go

@@ -291,6 +291,60 @@ func TestNodeProposeConfig(t *testing.T) {
 	}
 }
 
+// TestNodeProposeAddDuplicateNode ensures that two proposes to add the same node should
+// not affect the later propose to add new node.
+func TestNodeProposeAddDuplicateNode(t *testing.T) {
+	n := newNode()
+	s := NewMemoryStorage()
+	r := newTestRaft(1, []uint64{1}, 10, 1, s)
+	go n.run(r)
+	n.Campaign(context.TODO())
+	rdyEntries := make([]raftpb.Entry, 0)
+	ticker := time.NewTicker(time.Millisecond * 100)
+	go func() {
+		for {
+			select {
+			case <-ticker.C:
+				n.Tick()
+			case rd := <-n.Ready():
+				s.Append(rd.Entries)
+				for _, e := range rd.Entries {
+					rdyEntries = append(rdyEntries, e)
+					switch e.Type {
+					case raftpb.EntryNormal:
+					case raftpb.EntryConfChange:
+						var cc raftpb.ConfChange
+						cc.Unmarshal(e.Data)
+						n.ApplyConfChange(cc)
+					}
+				}
+				n.Advance()
+			}
+		}
+	}()
+	cc1 := raftpb.ConfChange{Type: raftpb.ConfChangeAddNode, NodeID: 1}
+	ccdata1, _ := cc1.Marshal()
+	n.ProposeConfChange(context.TODO(), cc1)
+	// try add the same node again
+	n.ProposeConfChange(context.TODO(), cc1)
+	// the new node join should be ok
+	cc2 := raftpb.ConfChange{Type: raftpb.ConfChangeAddNode, NodeID: 2}
+	ccdata2, _ := cc2.Marshal()
+	n.ProposeConfChange(context.TODO(), cc2)
+	time.Sleep(time.Second)
+
+	if len(rdyEntries) != 4 {
+		t.Errorf("len(entry) = %d, want %d, %v\n", len(rdyEntries), 3, rdyEntries)
+	}
+	if !bytes.Equal(rdyEntries[1].Data, ccdata1) {
+		t.Errorf("data = %v, want %v", rdyEntries[1].Data, ccdata1)
+	}
+	if !bytes.Equal(rdyEntries[3].Data, ccdata2) {
+		t.Errorf("data = %v, want %v", rdyEntries[3].Data, ccdata2)
+	}
+	n.Stop()
+}
+
 // TestBlockProposal ensures that node will block proposal when it does not
 // know who is the current leader; node will accept proposal when it knows
 // who is the current leader.