|
@@ -25,6 +25,32 @@ func increasePeerAddressPort(args []string, delta int) []string {
|
|
|
return append(args, "-peer-addr=127.0.0.1:"+strconv.Itoa(7001+delta))
|
|
return append(args, "-peer-addr=127.0.0.1:"+strconv.Itoa(7001+delta))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func increaseAddressPort(args []string, delta int) []string {
|
|
|
|
|
+ for i, arg := range args {
|
|
|
|
|
+ if !strings.HasPrefix(arg, "-addr") && !strings.HasPrefix(arg, "--addr") {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ splitArg := strings.Split(arg, ":")
|
|
|
|
|
+ port, _ := strconv.Atoi(splitArg[len(splitArg)-1])
|
|
|
|
|
+ args[i] = "-addr=127.0.0.1:" + strconv.Itoa(port+delta)
|
|
|
|
|
+ return args
|
|
|
|
|
+ }
|
|
|
|
|
+ return append(args, "-addr=127.0.0.1:"+strconv.Itoa(4001+delta))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func increaseDataDir(args []string, delta int) []string {
|
|
|
|
|
+ for i, arg := range args {
|
|
|
|
|
+ if !strings.Contains(arg, "-data-dir") {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ splitArg := strings.Split(arg, "node")
|
|
|
|
|
+ idx, _ := strconv.Atoi(splitArg[len(splitArg)-1])
|
|
|
|
|
+ args[i] = "-data-dir=/tmp/node" + strconv.Itoa(idx+delta)
|
|
|
|
|
+ return args
|
|
|
|
|
+ }
|
|
|
|
|
+ return args
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// Create a five-node cluster
|
|
// Create a five-node cluster
|
|
|
// Random kill one of the nodes and restart it with different peer address
|
|
// Random kill one of the nodes and restart it with different peer address
|
|
|
func TestRejoinWithDifferentPeerAddress(t *testing.T) {
|
|
func TestRejoinWithDifferentPeerAddress(t *testing.T) {
|
|
@@ -46,7 +72,6 @@ func TestRejoinWithDifferentPeerAddress(t *testing.T) {
|
|
|
num := rand.Int() % clusterSize
|
|
num := rand.Int() % clusterSize
|
|
|
fmt.Println("kill node", num+1)
|
|
fmt.Println("kill node", num+1)
|
|
|
|
|
|
|
|
- // kill
|
|
|
|
|
etcds[num].Kill()
|
|
etcds[num].Kill()
|
|
|
etcds[num].Release()
|
|
etcds[num].Release()
|
|
|
time.Sleep(time.Second)
|
|
time.Sleep(time.Second)
|
|
@@ -67,3 +92,57 @@ func TestRejoinWithDifferentPeerAddress(t *testing.T) {
|
|
|
t.Fatal("Failed to set value in etcd cluster")
|
|
t.Fatal("Failed to set value in etcd cluster")
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// Create a five-node cluster
|
|
|
|
|
+// Replace one of the nodes with different peer address
|
|
|
|
|
+func TestReplaceWithDifferentPeerAddress(t *testing.T) {
|
|
|
|
|
+ // TODO(yichengq): find some way to avoid the error that will be
|
|
|
|
|
+ // caused if some node joins the cluster with the collided name.
|
|
|
|
|
+ // Possible solutions:
|
|
|
|
|
+ // 1. Remove itself when executing a join command with the same name
|
|
|
|
|
+ // and different peer address. However, it should find some way to
|
|
|
|
|
+ // trigger that execution because the leader may update its address
|
|
|
|
|
+ // and stop heartbeat.
|
|
|
|
|
+ // 2. Remove the node with the same name before join each time.
|
|
|
|
|
+ // But this way could be rather overkill.
|
|
|
|
|
+ t.Skip("Unimplemented functionality")
|
|
|
|
|
+
|
|
|
|
|
+ procAttr := new(os.ProcAttr)
|
|
|
|
|
+ procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
|
|
|
|
|
+
|
|
|
|
|
+ clusterSize := 5
|
|
|
|
|
+ argGroup, etcds, err := CreateCluster(clusterSize, procAttr, false)
|
|
|
|
|
+
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatal("cannot create cluster")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ defer DestroyCluster(etcds)
|
|
|
|
|
+
|
|
|
|
|
+ time.Sleep(2 * time.Second)
|
|
|
|
|
+
|
|
|
|
|
+ rand.Int()
|
|
|
|
|
+ for i := 0; i < 10; i++ {
|
|
|
|
|
+ num := rand.Int() % clusterSize
|
|
|
|
|
+ fmt.Println("replace node", num+1)
|
|
|
|
|
+
|
|
|
|
|
+ argGroup[num] = increasePeerAddressPort(argGroup[num], clusterSize)
|
|
|
|
|
+ argGroup[num] = increaseAddressPort(argGroup[num], clusterSize)
|
|
|
|
|
+ argGroup[num] = increaseDataDir(argGroup[num], clusterSize)
|
|
|
|
|
+ // restart
|
|
|
|
|
+ newEtcd, err := os.StartProcess(EtcdBinPath, append(argGroup[num], "-f"), procAttr)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ panic(err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ etcds[num].Wait()
|
|
|
|
|
+ etcds[num] = newEtcd
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ c := etcd.NewClient(nil)
|
|
|
|
|
+ c.SyncCluster()
|
|
|
|
|
+ result, err := c.Set("foo", "bar", 0)
|
|
|
|
|
+ if err != nil || result.Node.Key != "/foo" || result.Node.Value != "bar" {
|
|
|
|
|
+ t.Fatal("Failed to set value in etcd cluster")
|
|
|
|
|
+ }
|
|
|
|
|
+}
|