|
|
@ -4,8 +4,9 @@ |
|
|
|
package api |
|
|
|
package api |
|
|
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
import ( |
|
|
|
"strings" |
|
|
|
|
|
|
|
"testing" |
|
|
|
"testing" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/consul/sdk/testutil" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
func TestAPI_OperatorRaftGetConfiguration(t *testing.T) { |
|
|
|
func TestAPI_OperatorRaftGetConfiguration(t *testing.T) { |
|
|
@ -27,33 +28,181 @@ func TestAPI_OperatorRaftGetConfiguration(t *testing.T) { |
|
|
|
|
|
|
|
|
|
|
|
func TestAPI_OperatorRaftRemovePeerByAddress(t *testing.T) { |
|
|
|
func TestAPI_OperatorRaftRemovePeerByAddress(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
t.Parallel() |
|
|
|
c, s := makeClient(t) |
|
|
|
c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
defer s.Stop() |
|
|
|
if conf.Autopilot == nil { |
|
|
|
|
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s1.Stop() |
|
|
|
|
|
|
|
|
|
|
|
// If we get this error, it proves we sent the address all the way
|
|
|
|
_, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
// through.
|
|
|
|
conf.Server = true |
|
|
|
operator := c.Operator() |
|
|
|
conf.Bootstrap = false |
|
|
|
err := operator.RaftRemovePeerByAddress("nope", nil) |
|
|
|
conf.RetryJoin = []string{s1.LANAddr} |
|
|
|
if err == nil || !strings.Contains(err.Error(), |
|
|
|
if conf.Autopilot == nil { |
|
|
|
"address \"nope\" was not found in the Raft configuration") { |
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s2.Stop() |
|
|
|
|
|
|
|
s2.WaitForVoting(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
operator := c1.Operator() |
|
|
|
|
|
|
|
err := operator.RaftRemovePeerByAddress(s2.ServerAddr, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cfg, err := c1.Operator().RaftGetConfiguration(nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(cfg.Servers) != 1 { |
|
|
|
|
|
|
|
t.Fatalf("more than 1 server left: %+v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func TestAPI_OperatorRaftRemovePeerByID(t *testing.T) { |
|
|
|
|
|
|
|
t.Parallel() |
|
|
|
|
|
|
|
c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
|
|
|
|
if conf.Autopilot == nil { |
|
|
|
|
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s1.Stop() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
|
|
|
|
conf.Server = true |
|
|
|
|
|
|
|
conf.Bootstrap = false |
|
|
|
|
|
|
|
conf.RetryJoin = []string{s1.LANAddr} |
|
|
|
|
|
|
|
if conf.Autopilot == nil { |
|
|
|
|
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s2.Stop() |
|
|
|
|
|
|
|
s2.WaitForVoting(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
operator := c1.Operator() |
|
|
|
|
|
|
|
err := operator.RaftRemovePeerByID(s2.Config.NodeID, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cfg, err := c1.Operator().RaftGetConfiguration(nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(cfg.Servers) != 1 { |
|
|
|
|
|
|
|
t.Fatalf("more than 1 server left: %+v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestAPI_OperatorRaftLeaderTransfer(t *testing.T) { |
|
|
|
func TestAPI_OperatorRaftLeaderTransfer(t *testing.T) { |
|
|
|
t.Parallel() |
|
|
|
t.Parallel() |
|
|
|
c, s := makeClient(t) |
|
|
|
c1, s1 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
defer s.Stop() |
|
|
|
if conf.Autopilot == nil { |
|
|
|
|
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s1.Stop() |
|
|
|
|
|
|
|
|
|
|
|
// If we get this error, it proves we sent the address all the way
|
|
|
|
_, s2 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
// through.
|
|
|
|
conf.Server = true |
|
|
|
operator := c.Operator() |
|
|
|
conf.Bootstrap = false |
|
|
|
transfer, err := operator.RaftLeaderTransfer(nil) |
|
|
|
conf.RetryJoin = []string{s1.LANAddr} |
|
|
|
if err == nil || !strings.Contains(err.Error(), |
|
|
|
if conf.Autopilot == nil { |
|
|
|
"cannot find peer") { |
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s2.Stop() |
|
|
|
|
|
|
|
s2.WaitForVoting(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cfg, err := c1.Operator().RaftGetConfiguration(nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if len(cfg.Servers) != 2 { |
|
|
|
|
|
|
|
t.Fatalf("not 2 servers: %#v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var leaderID string |
|
|
|
|
|
|
|
for _, srv := range cfg.Servers { |
|
|
|
|
|
|
|
if srv.Leader { |
|
|
|
|
|
|
|
leaderID = srv.ID |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if leaderID == "" { |
|
|
|
|
|
|
|
t.Fatalf("no leader: %+v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transfer, err := c1.Operator().RaftLeaderTransfer("", nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if !transfer.Success { |
|
|
|
|
|
|
|
t.Fatal("unsuccessful transfer") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s2.WaitForLeader(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cfg, err = c1.Operator().RaftGetConfiguration(nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
var newLeaderID string |
|
|
|
|
|
|
|
for _, srv := range cfg.Servers { |
|
|
|
|
|
|
|
if srv.Leader { |
|
|
|
|
|
|
|
newLeaderID = srv.ID |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if newLeaderID == "" { |
|
|
|
|
|
|
|
t.Fatalf("no leader: %#v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if newLeaderID == leaderID { |
|
|
|
|
|
|
|
t.Fatalf("leader did not change: %v == %v", newLeaderID, leaderID) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_, s3 := makeClientWithConfig(t, nil, func(conf *testutil.TestServerConfig) { |
|
|
|
|
|
|
|
conf.Server = true |
|
|
|
|
|
|
|
conf.Bootstrap = false |
|
|
|
|
|
|
|
conf.RetryJoin = []string{s1.LANAddr, s2.LANAddr} |
|
|
|
|
|
|
|
if conf.Autopilot == nil { |
|
|
|
|
|
|
|
conf.Autopilot = &testutil.TestAutopilotConfig{} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
conf.Autopilot.ServerStabilizationTime = "1ms" |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
defer s3.Stop() |
|
|
|
|
|
|
|
s3.WaitForVoting(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Transfer it to another member
|
|
|
|
|
|
|
|
transfer, err = c1.Operator().RaftLeaderTransfer(s3.Config.NodeID, nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
} |
|
|
|
} |
|
|
|
if transfer != nil { |
|
|
|
if !transfer.Success { |
|
|
|
t.Fatalf("err:%v", transfer) |
|
|
|
t.Fatal("unsuccessful transfer") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s3.WaitForLeader(t) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cfg, err = c1.Operator().RaftGetConfiguration(nil) |
|
|
|
|
|
|
|
if err != nil { |
|
|
|
|
|
|
|
t.Fatalf("err: %v", err) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
newLeaderID = "" |
|
|
|
|
|
|
|
for _, srv := range cfg.Servers { |
|
|
|
|
|
|
|
if srv.Leader { |
|
|
|
|
|
|
|
newLeaderID = srv.ID |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if newLeaderID == "" { |
|
|
|
|
|
|
|
t.Fatalf("no leader: %#v", cfg.Servers) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if newLeaderID != s3.Config.NodeID { |
|
|
|
|
|
|
|
t.Fatalf("leader is not s3: %v != %v", newLeaderID, s3.Config.NodeID) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|