etcd_test.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. package etcd
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/http/httptest"
  6. "net/url"
  7. "runtime"
  8. "testing"
  9. "time"
  10. "github.com/coreos/etcd/config"
  11. )
  12. func TestMultipleNodes(t *testing.T) {
  13. tests := []int{1, 3, 5, 9, 11}
  14. for _, tt := range tests {
  15. es, hs := buildCluster(tt, false)
  16. waitCluster(t, es)
  17. for i := range es {
  18. es[len(es)-i-1].Stop()
  19. }
  20. for i := range hs {
  21. hs[len(hs)-i-1].Close()
  22. }
  23. }
  24. afterTest(t)
  25. }
  26. func TestMultipleTLSNodes(t *testing.T) {
  27. tests := []int{1, 3, 5}
  28. for _, tt := range tests {
  29. es, hs := buildCluster(tt, true)
  30. waitCluster(t, es)
  31. for i := range es {
  32. es[len(es)-i-1].Stop()
  33. }
  34. for i := range hs {
  35. hs[len(hs)-i-1].Close()
  36. }
  37. }
  38. afterTest(t)
  39. }
  40. func TestV2Redirect(t *testing.T) {
  41. es, hs := buildCluster(3, false)
  42. waitCluster(t, es)
  43. u := hs[1].URL
  44. ru := fmt.Sprintf("%s%s", hs[0].URL, "/v2/keys/foo")
  45. tc := NewTestClient()
  46. v := url.Values{}
  47. v.Set("value", "XXX")
  48. resp, _ := tc.PutForm(fmt.Sprintf("%s%s", u, "/v2/keys/foo"), v)
  49. if resp.StatusCode != http.StatusTemporaryRedirect {
  50. t.Errorf("status = %d, want %d", resp.StatusCode, http.StatusTemporaryRedirect)
  51. }
  52. location, err := resp.Location()
  53. if err != nil {
  54. t.Errorf("want err = %, want nil", err)
  55. }
  56. if location.String() != ru {
  57. t.Errorf("location = %v, want %v", location.String(), ru)
  58. }
  59. resp.Body.Close()
  60. for i := range es {
  61. es[len(es)-i-1].Stop()
  62. }
  63. for i := range hs {
  64. hs[len(hs)-i-1].Close()
  65. }
  66. afterTest(t)
  67. }
  68. func TestRemove(t *testing.T) {
  69. tests := []struct {
  70. size int
  71. round int
  72. }{
  73. {3, 5},
  74. {4, 5},
  75. {5, 5},
  76. {6, 5},
  77. }
  78. for _, tt := range tests {
  79. es, hs := buildCluster(tt.size, false)
  80. waitCluster(t, es)
  81. // we don't remove the machine from 2-node cluster because it is
  82. // not 100 percent safe in our raft.
  83. // TODO(yichengq): improve it later.
  84. for i := 0; i < tt.size-2; i++ {
  85. // wait for leader to be stable for all live machines
  86. // TODO(yichengq): change it later
  87. var prevLead int64
  88. var prevTerm int64
  89. for j := i; j < tt.size; j++ {
  90. id := int64(i)
  91. lead := es[j].node.Leader()
  92. term := es[j].node.Term()
  93. fit := true
  94. if j == i {
  95. if lead < id {
  96. fit = false
  97. }
  98. } else {
  99. if lead != prevLead || term != prevTerm {
  100. fit = false
  101. }
  102. }
  103. if !fit {
  104. j = i - 1
  105. runtime.Gosched()
  106. continue
  107. }
  108. prevLead = lead
  109. prevTerm = term
  110. }
  111. index := es[i].Index()
  112. es[i].Remove(i)
  113. // i-th machine cannot be promised to apply the removal command of
  114. // its own due to our non-optimized raft.
  115. // TODO(yichengq): it should work when
  116. // https://github.com/etcd-team/etcd/pull/7 is merged.
  117. for j := i + 1; j < tt.size; j++ {
  118. w, err := es[j].Watch(v2machineKVPrefix, true, false, index+1)
  119. if err != nil {
  120. t.Errorf("#%d on %d: %v", i, j, err)
  121. break
  122. }
  123. v := <-w.EventChan
  124. ww := fmt.Sprintf("%s/%d", v2machineKVPrefix, i)
  125. if v.Node.Key != ww {
  126. t.Errorf("#%d on %d: path = %v, want %v", i, j, v.Node.Key, ww)
  127. }
  128. }
  129. // may need to wait for msgDenial
  130. // TODO(yichengq): no need to sleep here when previous issue is merged.
  131. if es[i].mode == stop {
  132. continue
  133. }
  134. time.Sleep(defaultElection * defaultTickDuration)
  135. if g := es[i].mode; g != stop {
  136. t.Errorf("#%d: mode = %d, want stop", i, g)
  137. }
  138. }
  139. for i := range hs {
  140. es[len(hs)-i-1].Stop()
  141. }
  142. for i := range hs {
  143. hs[len(hs)-i-1].Close()
  144. }
  145. afterTest(t)
  146. }
  147. }
  148. func buildCluster(number int, tls bool) ([]*Server, []*httptest.Server) {
  149. bootstrapper := 0
  150. es := make([]*Server, number)
  151. hs := make([]*httptest.Server, number)
  152. var seed string
  153. for i := range es {
  154. c := config.New()
  155. c.Peers = []string{seed}
  156. es[i] = New(c, int64(i))
  157. es[i].SetTick(time.Millisecond * 5)
  158. m := http.NewServeMux()
  159. m.Handle("/", es[i])
  160. m.Handle("/raft", es[i].t)
  161. m.Handle("/raft/", es[i].t)
  162. if tls {
  163. hs[i] = httptest.NewTLSServer(m)
  164. } else {
  165. hs[i] = httptest.NewServer(m)
  166. }
  167. es[i].raftPubAddr = hs[i].URL
  168. es[i].pubAddr = hs[i].URL
  169. if i == bootstrapper {
  170. seed = hs[i].URL
  171. go es[i].Bootstrap()
  172. } else {
  173. // wait for the previous configuration change to be committed
  174. // or this configuration request might be dropped
  175. w, err := es[0].Watch(v2machineKVPrefix, true, false, uint64(i))
  176. if err != nil {
  177. panic(err)
  178. }
  179. <-w.EventChan
  180. go es[i].Join()
  181. }
  182. }
  183. return es, hs
  184. }
  185. func waitCluster(t *testing.T, es []*Server) {
  186. n := len(es)
  187. for i, e := range es {
  188. for k := 1; k < n+1; k++ {
  189. w, err := e.Watch(v2machineKVPrefix, true, false, uint64(k))
  190. if err != nil {
  191. panic(err)
  192. }
  193. v := <-w.EventChan
  194. ww := fmt.Sprintf("%s/%d", v2machineKVPrefix, k-1)
  195. if v.Node.Key != ww {
  196. t.Errorf("#%d path = %v, want %v", i, v.Node.Key, w)
  197. }
  198. }
  199. }
  200. }