Jelajahi Sumber

fix(standby_server): able to join the cluster containing itself

Standby server will switch to peer server if it finds that
it has been contained in the cluster.
Yicheng Qin 11 tahun lalu
induk
melakukan
4bebb538eb
2 mengubah file dengan 66 tambahan dan 0 penghapusan
  1. 7 0
      server/standby_server.go
  2. 59 0
      tests/functional/standby_test.go

+ 7 - 0
server/standby_server.go

@@ -235,6 +235,13 @@ func (s *StandbyServer) syncCluster(peerURLs []string) error {
 }
 
 func (s *StandbyServer) join(peer string) error {
+	for _, url := range s.ClusterURLs() {
+		if s.Config.PeerURL == url {
+			s.joinIndex = 0
+			return nil
+		}
+	}
+
 	// Our version must match the leaders version
 	version, err := s.client.GetVersion(peer)
 	if err != nil {

+ 59 - 0
tests/functional/standby_test.go

@@ -8,6 +8,7 @@ import (
 	"time"
 
 	"github.com/coreos/etcd/server"
+	"github.com/coreos/etcd/store"
 	"github.com/coreos/etcd/tests"
 	"github.com/coreos/etcd/third_party/github.com/coreos/go-etcd/etcd"
 	"github.com/coreos/etcd/third_party/github.com/stretchr/testify/assert"
@@ -279,3 +280,61 @@ func TestStandbyDramaticChange(t *testing.T) {
 		}
 	}
 }
+
+func TestStandbyJoinMiss(t *testing.T) {
+	clusterSize := 2
+	_, etcds, err := CreateCluster(clusterSize, &os.ProcAttr{Files: []*os.File{nil, os.Stdout, os.Stderr}}, false)
+	if err != nil {
+		t.Fatal("cannot create cluster")
+	}
+	defer DestroyCluster(etcds)
+
+	c := etcd.NewClient(nil)
+	c.SyncCluster()
+
+	time.Sleep(1 * time.Second)
+
+	// Verify that we have two machines.
+	result, err := c.Get("_etcd/machines", false, true)
+	assert.NoError(t, err)
+	assert.Equal(t, len(result.Node.Nodes), clusterSize)
+
+	resp, _ := tests.Put("http://localhost:7001/v2/admin/config", "application/json", bytes.NewBufferString(`{"removeDelay":4, "syncInterval":4}`))
+	if !assert.Equal(t, resp.StatusCode, 200) {
+		t.FailNow()
+	}
+	time.Sleep(time.Second)
+
+	resp, _ = tests.Delete("http://localhost:7001/v2/admin/machines/node2", "application/json", nil)
+	if !assert.Equal(t, resp.StatusCode, 200) {
+		t.FailNow()
+	}
+
+	// Wait for a monitor cycle before checking for removal.
+	time.Sleep(server.ActiveMonitorTimeout + (1 * time.Second))
+
+	// Verify that we now have four peers.
+	result, err = c.Get("_etcd/machines", false, true)
+	assert.NoError(t, err)
+	assert.Equal(t, len(result.Node.Nodes), 1)
+
+	// Simulate the join failure
+	_, err = server.NewClient(nil).AddMachine("http://localhost:7001",
+		&server.JoinCommand{
+			MinVersion: store.MinVersion(),
+			MaxVersion: store.MaxVersion(),
+			Name:       "node2",
+			RaftURL:    "http://127.0.0.1:7002",
+			EtcdURL:    "http://127.0.0.1:4002",
+		})
+	assert.NoError(t, err)
+
+	time.Sleep(6 * time.Second)
+
+	go tests.Delete("http://localhost:7001/v2/admin/machines/node2", "application/json", nil)
+
+	time.Sleep(time.Second)
+	result, err = c.Get("_etcd/machines", false, true)
+	assert.NoError(t, err)
+	assert.Equal(t, len(result.Node.Nodes), 1)
+}