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  }