Browse Source

etcdserver: add test for isReadyToAddNewMember

Also fixed check for special case of one-member cluster
Jonathan Boulle 10 years ago
parent
commit
d9cf752060
2 changed files with 66 additions and 1 deletions
  1. 1 1
      etcdserver/cluster.go
  2. 65 0
      etcdserver/cluster_test.go

+ 1 - 1
etcdserver/cluster.go

@@ -379,7 +379,7 @@ func (c *cluster) isReadyToAddNewMember() bool {
 		nmembers++
 	}
 
-	if nstarted == 1 {
+	if nstarted == 1 && nmembers == 2 {
 		// a case of adding a new node to 1-member cluster for restoring cluster data
 		// https://github.com/coreos/etcd/blob/master/Documentation/admin_guide.md#restoring-the-cluster
 

+ 65 - 0
etcdserver/cluster_test.go

@@ -566,3 +566,68 @@ func newTestCluster(membs []*Member) *cluster {
 }
 
 func stringp(s string) *string { return &s }
+
+func TestIsReadyToAddNewMember(t *testing.T) {
+	tests := []struct {
+		members []*Member
+		want    bool
+	}{
+		{
+			// 0/3 members ready, should fail
+			[]*Member{
+				newTestMember(1, nil, "", nil),
+				newTestMember(2, nil, "", nil),
+				newTestMember(3, nil, "", nil),
+			},
+			false,
+		},
+		{
+			// 1/2 members ready, should fail
+			[]*Member{
+				newTestMember(1, nil, "1", nil),
+				newTestMember(2, nil, "", nil),
+			},
+			false,
+		},
+		{
+			// 1/3 members ready, should fail
+			[]*Member{
+				newTestMember(1, nil, "1", nil),
+				newTestMember(2, nil, "", nil),
+				newTestMember(3, nil, "", nil),
+			},
+			false,
+		},
+		{
+			// 1/1 members ready, should succeed (special case of 1-member cluster for recovery)
+			[]*Member{
+				newTestMember(1, nil, "1", nil),
+			},
+			true,
+		},
+		{
+			// 2/3 members ready, should fail
+			[]*Member{
+				newTestMember(1, nil, "1", nil),
+				newTestMember(2, nil, "2", nil),
+				newTestMember(3, nil, "", nil),
+			},
+			false,
+		},
+		{
+			// 3/3 members ready, should be fine to add one member and retain quorum
+			[]*Member{
+				newTestMember(1, nil, "1", nil),
+				newTestMember(2, nil, "2", nil),
+				newTestMember(3, nil, "3", nil),
+			},
+			true,
+		},
+	}
+	for i, tt := range tests {
+		c := newTestCluster(tt.members)
+		if got := c.isReadyToAddNewMember(); got != tt.want {
+			t.Errorf("%d: isReadyToAddNewMember returned %t, want %t", i, got, tt.want)
+		}
+	}
+}