etcd_test.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package main
  2. import (
  3. "fmt"
  4. "github.com/coreos/go-etcd/etcd"
  5. "math/rand"
  6. "os"
  7. //"strconv"
  8. "testing"
  9. "time"
  10. )
  11. // Create a single node and try to set value
  12. func TestSingleNode(t *testing.T) {
  13. procAttr := new(os.ProcAttr)
  14. procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
  15. args := []string{"etcd", "-i", "-d=/tmp/node1"}
  16. process, err := os.StartProcess("etcd", args, procAttr)
  17. if err != nil {
  18. t.Fatal("start process failed:" + err.Error())
  19. return
  20. }
  21. defer process.Kill()
  22. time.Sleep(time.Second)
  23. etcd.SyncCluster()
  24. // Test Set
  25. result, err := etcd.Set("foo", "bar", 100)
  26. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL != 99 {
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. t.Fatalf("Set 1 failed with %s %s %v", result.Key, result.Value, result.TTL)
  31. }
  32. time.Sleep(time.Second)
  33. result, err = etcd.Set("foo", "bar", 100)
  34. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.PrevValue != "bar" || result.TTL != 99 {
  35. if err != nil {
  36. t.Fatal(err)
  37. }
  38. t.Fatalf("Set 2 failed with %s %s %v", result.Key, result.Value, result.TTL)
  39. }
  40. }
  41. // This test creates a single node and then set a value to it.
  42. // Then this test kills the node and restart it and tries to get the value again.
  43. func TestSingleNodeRecovery(t *testing.T) {
  44. procAttr := new(os.ProcAttr)
  45. procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
  46. args := []string{"etcd", "-d=/tmp/node1"}
  47. process, err := os.StartProcess("etcd", append(args, "-i"), procAttr)
  48. if err != nil {
  49. t.Fatal("start process failed:" + err.Error())
  50. return
  51. }
  52. time.Sleep(time.Second)
  53. etcd.SyncCluster()
  54. // Test Set
  55. result, err := etcd.Set("foo", "bar", 100)
  56. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL != 99 {
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. t.Fatalf("Set 1 failed with %s %s %v", result.Key, result.Value, result.TTL)
  61. }
  62. time.Sleep(time.Second)
  63. process.Kill()
  64. process, err = os.StartProcess("etcd", args, procAttr)
  65. defer process.Kill()
  66. if err != nil {
  67. t.Fatal("start process failed:" + err.Error())
  68. return
  69. }
  70. time.Sleep(time.Second)
  71. results, err := etcd.Get("foo")
  72. if err != nil {
  73. t.Fatal("get fail: " + err.Error())
  74. return
  75. }
  76. result = results[0]
  77. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL > 99 {
  78. if err != nil {
  79. t.Fatal(err)
  80. }
  81. t.Fatalf("Recovery Get failed with %s %s %v", result.Key, result.Value, result.TTL)
  82. }
  83. }
  84. // Create a three nodes and try to set value
  85. func TestSimpleMultiNode(t *testing.T) {
  86. procAttr := new(os.ProcAttr)
  87. procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
  88. clusterSize := 3
  89. _, etcds, err := createCluster(clusterSize, procAttr)
  90. if err != nil {
  91. t.Fatal("cannot create cluster")
  92. }
  93. defer destroyCluster(etcds)
  94. time.Sleep(time.Second)
  95. etcd.SyncCluster()
  96. // Test Set
  97. result, err := etcd.Set("foo", "bar", 100)
  98. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.TTL != 99 {
  99. if err != nil {
  100. t.Fatal(err)
  101. }
  102. t.Fatalf("Set 1 failed with %s %s %v", result.Key, result.Value, result.TTL)
  103. }
  104. time.Sleep(time.Second)
  105. result, err = etcd.Set("foo", "bar", 100)
  106. if err != nil || result.Key != "/foo" || result.Value != "bar" || result.PrevValue != "bar" || result.TTL != 99 {
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. t.Fatalf("Set 2 failed with %s %s %v", result.Key, result.Value, result.TTL)
  111. }
  112. }
  113. // Create a five nodes
  114. // Randomly kill one of the node and keep on sending set command to the cluster
  115. func TestMultiNodeRecovery(t *testing.T) {
  116. procAttr := new(os.ProcAttr)
  117. procAttr.Files = []*os.File{nil, os.Stdout, os.Stderr}
  118. clusterSize := 5
  119. argGroup, etcds, err := createCluster(clusterSize, procAttr)
  120. if err != nil {
  121. t.Fatal("cannot create cluster")
  122. }
  123. defer destroyCluster(etcds)
  124. time.Sleep(2 * time.Second)
  125. etcd.SyncCluster()
  126. stop := make(chan bool)
  127. // Test Set
  128. go set(stop)
  129. for i := 0; i < 10; i++ {
  130. num := rand.Int() % clusterSize
  131. fmt.Println("kill node", num+1)
  132. // kill
  133. etcds[num].Kill()
  134. etcds[num].Release()
  135. time.Sleep(time.Second)
  136. // restart
  137. etcds[num], err = os.StartProcess("etcd", argGroup[num], procAttr)
  138. if err != nil {
  139. panic(err)
  140. }
  141. time.Sleep(time.Second)
  142. }
  143. fmt.Println("stop")
  144. stop <- true
  145. <-stop
  146. }