v2_http_endpoint_test.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. package etcd
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "net/http"
  8. "reflect"
  9. "sort"
  10. "strings"
  11. "testing"
  12. "github.com/coreos/etcd/config"
  13. "github.com/coreos/etcd/store"
  14. )
  15. func TestMachinesEndPoint(t *testing.T) {
  16. es, hs := buildCluster(3, false)
  17. waitCluster(t, es)
  18. w := make([]string, len(hs))
  19. for i := range hs {
  20. w[i] = hs[i].URL
  21. }
  22. for i := range hs {
  23. r, err := http.Get(hs[i].URL + v2machinePrefix)
  24. if err != nil {
  25. t.Errorf("%v", err)
  26. break
  27. }
  28. b, err := ioutil.ReadAll(r.Body)
  29. r.Body.Close()
  30. if err != nil {
  31. t.Errorf("%v", err)
  32. break
  33. }
  34. g := strings.Split(string(b), ",")
  35. sort.Strings(g)
  36. if !reflect.DeepEqual(w, g) {
  37. t.Errorf("machines = %v, want %v", g, w)
  38. }
  39. }
  40. for i := range es {
  41. es[len(es)-i-1].Stop()
  42. }
  43. for i := range hs {
  44. hs[len(hs)-i-1].Close()
  45. }
  46. afterTest(t)
  47. }
  48. func TestLeaderEndPoint(t *testing.T) {
  49. es, hs := buildCluster(3, false)
  50. waitCluster(t, es)
  51. us := make([]string, len(hs))
  52. for i := range hs {
  53. us[i] = hs[i].URL
  54. }
  55. // todo(xiangli) change this to raft port...
  56. w := hs[0].URL + "/raft"
  57. for i := range hs {
  58. r, err := http.Get(hs[i].URL + v2LeaderPrefix)
  59. if err != nil {
  60. t.Errorf("%v", err)
  61. break
  62. }
  63. b, err := ioutil.ReadAll(r.Body)
  64. r.Body.Close()
  65. if err != nil {
  66. t.Errorf("%v", err)
  67. break
  68. }
  69. if string(b) != w {
  70. t.Errorf("leader = %v, want %v", string(b), w)
  71. }
  72. }
  73. for i := range es {
  74. es[len(es)-i-1].Stop()
  75. }
  76. for i := range hs {
  77. hs[len(hs)-i-1].Close()
  78. }
  79. afterTest(t)
  80. }
  81. func TestStoreStatsEndPoint(t *testing.T) {
  82. es, hs := buildCluster(1, false)
  83. waitCluster(t, es)
  84. resp, err := http.Get(hs[0].URL + v2StoreStatsPrefix)
  85. if err != nil {
  86. t.Errorf("%v", err)
  87. }
  88. stats := new(store.Stats)
  89. d := json.NewDecoder(resp.Body)
  90. err = d.Decode(stats)
  91. resp.Body.Close()
  92. if err != nil {
  93. t.Errorf("%v", err)
  94. }
  95. if stats.SetSuccess != 1 {
  96. t.Errorf("setSuccess = %d, want 1", stats.SetSuccess)
  97. }
  98. for i := range es {
  99. es[len(es)-i-1].Stop()
  100. }
  101. for i := range hs {
  102. hs[len(hs)-i-1].Close()
  103. }
  104. afterTest(t)
  105. }
  106. func TestGetAdminConfigEndPoint(t *testing.T) {
  107. es, hs := buildCluster(3, false)
  108. waitCluster(t, es)
  109. for i := range hs {
  110. r, err := http.Get(hs[i].URL + v2adminConfigPrefix)
  111. if err != nil {
  112. t.Errorf("%v", err)
  113. continue
  114. }
  115. if g := r.StatusCode; g != 200 {
  116. t.Errorf("#%d: status = %d, want %d", i, g, 200)
  117. }
  118. if g := r.Header.Get("Content-Type"); g != "application/json" {
  119. t.Errorf("#%d: ContentType = %d, want application/json", i, g)
  120. }
  121. conf := new(config.ClusterConfig)
  122. err = json.NewDecoder(r.Body).Decode(conf)
  123. r.Body.Close()
  124. if err != nil {
  125. t.Errorf("%v", err)
  126. continue
  127. }
  128. w := config.NewClusterConfig()
  129. if !reflect.DeepEqual(conf, w) {
  130. t.Errorf("#%d: config = %+v, want %+v", i, conf, w)
  131. }
  132. }
  133. for i := range es {
  134. es[len(es)-i-1].Stop()
  135. }
  136. for i := range hs {
  137. hs[len(hs)-i-1].Close()
  138. }
  139. afterTest(t)
  140. }
  141. func TestPutAdminConfigEndPoint(t *testing.T) {
  142. tests := []struct {
  143. c, wc string
  144. }{
  145. {
  146. `{"activeSize":1,"removeDelay":1,"syncInterval":1}`,
  147. `{"activeSize":3,"removeDelay":2,"syncInterval":1}`,
  148. },
  149. {
  150. `{"activeSize":5,"removeDelay":20.5,"syncInterval":1.5}`,
  151. `{"activeSize":5,"removeDelay":20.5,"syncInterval":1.5}`,
  152. },
  153. {
  154. `{"activeSize":5 , "removeDelay":20 , "syncInterval": 2 }`,
  155. `{"activeSize":5,"removeDelay":20,"syncInterval":2}`,
  156. },
  157. {
  158. `{"activeSize":3, "removeDelay":60}`,
  159. `{"activeSize":3,"removeDelay":60,"syncInterval":5}`,
  160. },
  161. }
  162. for i, tt := range tests {
  163. es, hs := buildCluster(3, false)
  164. waitCluster(t, es)
  165. index := es[0].p.Index()
  166. r, err := NewTestClient().Put(hs[0].URL+v2adminConfigPrefix, "application/json", bytes.NewBufferString(tt.c))
  167. if err != nil {
  168. t.Fatalf("%v", err)
  169. }
  170. b, err := ioutil.ReadAll(r.Body)
  171. r.Body.Close()
  172. if err != nil {
  173. t.Fatalf("%v", err)
  174. }
  175. if wbody := append([]byte(tt.wc), '\n'); !reflect.DeepEqual(b, wbody) {
  176. t.Errorf("#%d: put result = %s, want %s", i, b, wbody)
  177. }
  178. for j := range es {
  179. w, err := es[j].p.Watch(v2configKVPrefix, false, false, index)
  180. if err != nil {
  181. t.Errorf("%v", err)
  182. continue
  183. }
  184. e := <-w.EventChan
  185. if g := *e.Node.Value; g != tt.wc {
  186. t.Errorf("#%d.%d: %s = %s, want %s", i, j, v2configKVPrefix, g, tt.wc)
  187. }
  188. }
  189. for j := range es {
  190. es[len(es)-j-1].Stop()
  191. }
  192. for j := range hs {
  193. hs[len(hs)-j-1].Close()
  194. }
  195. }
  196. afterTest(t)
  197. }
  198. func TestGetAdminMachineEndPoint(t *testing.T) {
  199. es, hs := buildCluster(3, false)
  200. waitCluster(t, es)
  201. for i := range es {
  202. for j := range hs {
  203. name := fmt.Sprint(es[i].id)
  204. r, err := http.Get(hs[j].URL + v2adminMachinesPrefix + name)
  205. if err != nil {
  206. t.Errorf("%v", err)
  207. continue
  208. }
  209. if g := r.StatusCode; g != 200 {
  210. t.Errorf("#%d on %d: status = %d, want %d", i, j, g, 200)
  211. }
  212. if g := r.Header.Get("Content-Type"); g != "application/json" {
  213. t.Errorf("#%d on %d: ContentType = %d, want application/json", i, j, g)
  214. }
  215. m := new(machineMessage)
  216. err = json.NewDecoder(r.Body).Decode(m)
  217. r.Body.Close()
  218. if err != nil {
  219. t.Errorf("%v", err)
  220. continue
  221. }
  222. wm := &machineMessage{
  223. Name: name,
  224. State: stateFollower,
  225. ClientURL: hs[i].URL,
  226. PeerURL: hs[i].URL,
  227. }
  228. if i == 0 {
  229. wm.State = stateLeader
  230. }
  231. if !reflect.DeepEqual(m, wm) {
  232. t.Errorf("#%d on %d: body = %+v, want %+v", i, j, m, wm)
  233. }
  234. }
  235. }
  236. for i := range es {
  237. es[len(es)-i-1].Stop()
  238. }
  239. for i := range hs {
  240. hs[len(hs)-i-1].Close()
  241. }
  242. afterTest(t)
  243. }
  244. func TestGetAdminMachinesEndPoint(t *testing.T) {
  245. es, hs := buildCluster(3, false)
  246. waitCluster(t, es)
  247. w := make([]*machineMessage, len(hs))
  248. for i := range hs {
  249. w[i] = &machineMessage{
  250. Name: fmt.Sprint(es[i].id),
  251. State: stateFollower,
  252. ClientURL: hs[i].URL,
  253. PeerURL: hs[i].URL,
  254. }
  255. }
  256. w[0].State = stateLeader
  257. for i := range hs {
  258. r, err := http.Get(hs[i].URL + v2adminMachinesPrefix)
  259. if err != nil {
  260. t.Errorf("%v", err)
  261. continue
  262. }
  263. m := make([]*machineMessage, 0)
  264. err = json.NewDecoder(r.Body).Decode(&m)
  265. r.Body.Close()
  266. if err != nil {
  267. t.Errorf("%v", err)
  268. continue
  269. }
  270. sm := machineSlice(m)
  271. sw := machineSlice(w)
  272. sort.Sort(sm)
  273. sort.Sort(sw)
  274. if !reflect.DeepEqual(sm, sw) {
  275. t.Errorf("on %d: machines = %+v, want %+v", i, sm, sw)
  276. }
  277. }
  278. for i := range es {
  279. es[len(es)-i-1].Stop()
  280. }
  281. for i := range hs {
  282. hs[len(hs)-i-1].Close()
  283. }
  284. afterTest(t)
  285. }
  286. // int64Slice implements sort interface
  287. type machineSlice []*machineMessage
  288. func (s machineSlice) Len() int { return len(s) }
  289. func (s machineSlice) Less(i, j int) bool { return s[i].Name < s[j].Name }
  290. func (s machineSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }