Browse Source

integration: improve TestTransferLeader

so that it can check leader transition
Gyu-Ho Lee 9 years ago
parent
commit
eaa5d9772f
2 changed files with 36 additions and 25 deletions
  1. 7 7
      integration/cluster.go
  2. 29 18
      integration/cluster_test.go

+ 7 - 7
integration/cluster.go

@@ -702,13 +702,13 @@ func (m *member) Stop(t *testing.T) {
 	plog.Printf("stopped %s (%s)", m.Name, m.grpcAddr)
 }
 
-// StopWithAutoLeaderTransfer stops the member with auto leader transfer.
-func (m *member) StopWithAutoLeaderTransfer(t *testing.T) {
-	plog.Printf("stopping %s (%s)", m.Name, m.grpcAddr)
-	m.s.TransferLeadership()
-	m.Close()
-	m.hss = nil
-	plog.Printf("stopped %s (%s)", m.Name, m.grpcAddr)
+// checkLeaderTransition waits for leader transition, returning the new leader ID.
+func checkLeaderTransition(t *testing.T, m *member, oldLead uint64) uint64 {
+	interval := time.Duration(m.s.Cfg.TickMs) * time.Millisecond
+	for m.s.Lead() == 0 || (m.s.Lead() == oldLead) {
+		time.Sleep(interval)
+	}
+	return m.s.Lead()
 }
 
 // StopNotify unblocks when a member stop completes

+ 29 - 18
integration/cluster_test.go

@@ -26,7 +26,6 @@ import (
 
 	"github.com/coreos/etcd/client"
 	"github.com/coreos/etcd/etcdserver"
-	"github.com/coreos/etcd/etcdserver/etcdserverpb"
 	"github.com/coreos/etcd/pkg/testutil"
 
 	"golang.org/x/net/context"
@@ -470,29 +469,41 @@ func TestTransferLeader(t *testing.T) {
 	clus := NewClusterV3(t, &ClusterConfig{Size: 3})
 	defer clus.Terminate(t)
 
-	leaderIdx := clus.WaitLeader(t)
+	oldLeadIdx := clus.WaitLeader(t)
+	oldLeadID := uint64(clus.Members[oldLeadIdx].s.ID())
+
+	// ensure followers go through leader transition while learship transfer
+	idc := make(chan uint64)
+	for i := range clus.Members {
+		if oldLeadIdx != i {
+			go func(m *member) {
+				idc <- checkLeaderTransition(t, m, oldLeadID)
+			}(clus.Members[i])
+		}
+	}
 
-	err := clus.Members[leaderIdx].s.TransferLeadership()
+	err := clus.Members[oldLeadIdx].s.TransferLeadership()
 	if err != nil {
 		t.Fatal(err)
 	}
-}
 
-func TestTransferLeaderStopTrigger(t *testing.T) {
-	defer testutil.AfterTest(t)
-
-	clus := NewClusterV3(t, &ClusterConfig{Size: 3})
-	defer clus.Terminate(t)
+	// wait until leader transitions have happened
+	var newLeadIDs [2]uint64
+	for i := range newLeadIDs {
+		select {
+		case newLeadIDs[i] = <-idc:
+		case <-time.After(time.Second):
+			t.Fatal("timed out waiting for leader transition")
+		}
+	}
 
-	oldLeadIdx := clus.WaitLeader(t)
-	clus.Members[oldLeadIdx].StopWithAutoLeaderTransfer(t)
+	// remaining members must agree on the same leader
+	if newLeadIDs[0] != newLeadIDs[1] {
+		t.Fatalf("expected same new leader %d == %d", newLeadIDs[0], newLeadIDs[1])
+	}
 
-	// issue put to one of the other member
-	kvc := toGRPC(clus.Client((oldLeadIdx + 1) % 3)).KV
-	sctx, scancel := context.WithTimeout(context.TODO(), clus.Members[oldLeadIdx].electionTimeout())
-	_, err := kvc.Range(sctx, &etcdserverpb.RangeRequest{Key: []byte("foo")})
-	scancel()
-	if err != nil {
-		t.Fatal(err)
+	// new leader must be different than the old leader
+	if oldLeadID == newLeadIDs[0] {
+		t.Fatalf("expected old leader %d != new leader %d", oldLeadID, newLeadIDs[0])
 	}
 }