From c5532dd2a241214f3488475f2a8ff7de653ecf4e Mon Sep 17 00:00:00 2001 From: Gyu-Ho Lee Date: Fri, 23 Jun 2017 12:53:22 -0700 Subject: [PATCH] integration: test 'MoveLeader' service Signed-off-by: Gyu-Ho Lee --- integration/cluster_test.go | 45 ------------- integration/v3_leadership_test.go | 108 ++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 integration/v3_leadership_test.go diff --git a/integration/cluster_test.go b/integration/cluster_test.go index 5a1040adb..5907d6841 100644 --- a/integration/cluster_test.go +++ b/integration/cluster_test.go @@ -526,51 +526,6 @@ func clusterMustProgress(t *testing.T, membs []*member) { } } -func TestTransferLeader(t *testing.T) { - defer testutil.AfterTest(t) - - clus := NewClusterV3(t, &ClusterConfig{Size: 3}) - defer clus.Terminate(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[oldLeadIdx].s.TransferLeadership() - if err != nil { - t.Fatal(err) - } - - // 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") - } - } - - // 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]) - } - - // 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]) - } -} - func TestSpeedyTerminate(t *testing.T) { defer testutil.AfterTest(t) clus := NewClusterV3(t, &ClusterConfig{Size: 3}) diff --git a/integration/v3_leadership_test.go b/integration/v3_leadership_test.go new file mode 100644 index 000000000..7f41f3bfe --- /dev/null +++ b/integration/v3_leadership_test.go @@ -0,0 +1,108 @@ +// Copyright 2017 The etcd Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package integration + +import ( + "context" + "testing" + "time" + + "github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes" + pb "github.com/coreos/etcd/etcdserver/etcdserverpb" + "github.com/coreos/etcd/pkg/testutil" +) + +func TestMoveLeader(t *testing.T) { testMoveLeader(t, true) } +func TestMoveLeaderService(t *testing.T) { testMoveLeader(t, false) } + +func testMoveLeader(t *testing.T, auto bool) { + defer testutil.AfterTest(t) + + clus := NewClusterV3(t, &ClusterConfig{Size: 3}) + defer clus.Terminate(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]) + } + } + + target := uint64(clus.Members[(oldLeadIdx+1)%3].s.ID()) + if auto { + err := clus.Members[oldLeadIdx].s.TransferLeadership() + if err != nil { + t.Fatal(err) + } + } else { + mvc := toGRPC(clus.Client(oldLeadIdx)).Maintenance + _, err := mvc.MoveLeader(context.TODO(), &pb.MoveLeaderRequest{TargetID: target}) + if err != nil { + t.Fatal(err) + } + } + + // 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") + } + } + + // 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]) + } + + // 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]) + } + + // if move-leader were used, new leader must match transferee + if !auto { + if newLeadIDs[0] != target { + t.Fatalf("expected new leader %d != target %d", newLeadIDs[0], target) + } + } +} + +// TestMoveLeaderError ensures that request to non-leader fail. +func TestMoveLeaderError(t *testing.T) { + defer testutil.AfterTest(t) + + clus := NewClusterV3(t, &ClusterConfig{Size: 3}) + defer clus.Terminate(t) + + oldLeadIdx := clus.WaitLeader(t) + followerIdx := (oldLeadIdx + 1) % 3 + + target := uint64(clus.Members[(oldLeadIdx+2)%3].s.ID()) + + mvc := toGRPC(clus.Client(followerIdx)).Maintenance + _, err := mvc.MoveLeader(context.TODO(), &pb.MoveLeaderRequest{TargetID: target}) + if !eqErrGRPC(err, rpctypes.ErrGRPCNotLeader) { + t.Errorf("err = %v, want %v", err, rpctypes.ErrGRPCNotLeader) + } +}