github.com/ghodss/etcd@v0.3.1-0.20140417172404-cc329bfa55cb/tests/functional/rejoin_test.go (about) 1 package test 2 3 import ( 4 "fmt" 5 "math/rand" 6 "os" 7 "strconv" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/coreos/etcd/third_party/github.com/coreos/go-etcd/etcd" 13 ) 14 15 func increasePeerAddressPort(args []string, delta int) []string { 16 for i, arg := range args { 17 if !strings.Contains(arg, "peer-addr") { 18 continue 19 } 20 splitArg := strings.Split(arg, ":") 21 port, _ := strconv.Atoi(splitArg[len(splitArg)-1]) 22 args[i] = "-peer-addr=127.0.0.1:" + strconv.Itoa(port+delta) 23 return args 24 } 25 return append(args, "-peer-addr=127.0.0.1:"+strconv.Itoa(7001+delta)) 26 } 27 28 func increaseAddressPort(args []string, delta int) []string { 29 for i, arg := range args { 30 if !strings.HasPrefix(arg, "-addr") && !strings.HasPrefix(arg, "--addr") { 31 continue 32 } 33 splitArg := strings.Split(arg, ":") 34 port, _ := strconv.Atoi(splitArg[len(splitArg)-1]) 35 args[i] = "-addr=127.0.0.1:" + strconv.Itoa(port+delta) 36 return args 37 } 38 return append(args, "-addr=127.0.0.1:"+strconv.Itoa(4001+delta)) 39 } 40 41 func increaseDataDir(args []string, delta int) []string { 42 for i, arg := range args { 43 if !strings.Contains(arg, "-data-dir") { 44 continue 45 } 46 splitArg := strings.Split(arg, "node") 47 idx, _ := strconv.Atoi(splitArg[len(splitArg)-1]) 48 args[i] = "-data-dir=/tmp/node" + strconv.Itoa(idx+delta) 49 return args 50 } 51 return args 52 } 53 54 // Create a five-node cluster 55 // Random kill one of the nodes and restart it with different peer address 56 func TestRejoinWithDifferentPeerAddress(t *testing.T) { 57 procAttr := new(os.ProcAttr) 58 procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr} 59 60 clusterSize := 5 61 argGroup, etcds, err := CreateCluster(clusterSize, procAttr, false) 62 63 if err != nil { 64 t.Fatal("cannot create cluster") 65 } 66 67 defer DestroyCluster(etcds) 68 69 time.Sleep(2 * time.Second) 70 71 for i := 0; i < 10; i++ { 72 num := rand.Int() % clusterSize 73 fmt.Println("kill node", num+1) 74 75 etcds[num].Kill() 76 etcds[num].Release() 77 time.Sleep(time.Second) 78 79 argGroup[num] = increasePeerAddressPort(argGroup[num], clusterSize) 80 // restart 81 etcds[num], err = os.StartProcess(EtcdBinPath, argGroup[num], procAttr) 82 if err != nil { 83 panic(err) 84 } 85 time.Sleep(time.Second) 86 } 87 88 c := etcd.NewClient(nil) 89 c.SyncCluster() 90 result, err := c.Set("foo", "bar", 0) 91 if err != nil || result.Node.Key != "/foo" || result.Node.Value != "bar" { 92 t.Fatal("Failed to set value in etcd cluster") 93 } 94 } 95 96 // Create a five-node cluster 97 // Replace one of the nodes with different peer address 98 func TestReplaceWithDifferentPeerAddress(t *testing.T) { 99 // TODO(yichengq): find some way to avoid the error that will be 100 // caused if some node joins the cluster with the collided name. 101 // Possible solutions: 102 // 1. Remove itself when executing a join command with the same name 103 // and different peer address. However, it should find some way to 104 // trigger that execution because the leader may update its address 105 // and stop heartbeat. 106 // 2. Remove the node with the same name before join each time. 107 // But this way could be rather overkill. 108 t.Skip("Unimplemented functionality") 109 110 procAttr := new(os.ProcAttr) 111 procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr} 112 113 clusterSize := 5 114 argGroup, etcds, err := CreateCluster(clusterSize, procAttr, false) 115 116 if err != nil { 117 t.Fatal("cannot create cluster") 118 } 119 120 defer DestroyCluster(etcds) 121 122 time.Sleep(2 * time.Second) 123 124 rand.Int() 125 for i := 0; i < 10; i++ { 126 num := rand.Int() % clusterSize 127 fmt.Println("replace node", num+1) 128 129 argGroup[num] = increasePeerAddressPort(argGroup[num], clusterSize) 130 argGroup[num] = increaseAddressPort(argGroup[num], clusterSize) 131 argGroup[num] = increaseDataDir(argGroup[num], clusterSize) 132 // restart 133 newEtcd, err := os.StartProcess(EtcdBinPath, append(argGroup[num], "-f"), procAttr) 134 if err != nil { 135 panic(err) 136 } 137 138 etcds[num].Wait() 139 etcds[num] = newEtcd 140 } 141 142 c := etcd.NewClient(nil) 143 c.SyncCluster() 144 result, err := c.Set("foo", "bar", 0) 145 if err != nil || result.Node.Key != "/foo" || result.Node.Value != "bar" { 146 t.Fatal("Failed to set value in etcd cluster") 147 } 148 }