Browse Source

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 years ago
parent
commit
4bebb538eb
2 changed files with 66 additions and 0 deletions
  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)
+}