discovery_test.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. package discovery
  2. import (
  3. "errors"
  4. "math/rand"
  5. "sort"
  6. "reflect"
  7. "testing"
  8. "time"
  9. "github.com/coreos/etcd/client"
  10. )
  11. func TestCheckCluster(t *testing.T) {
  12. cluster := "1000"
  13. self := "/1000/1"
  14. tests := []struct {
  15. nodes []*client.Node
  16. werr error
  17. wsize int
  18. }{
  19. {
  20. // self is in the size range
  21. client.Nodes{
  22. {Key: "/1000/_config/size", Value: "3", CreatedIndex: 1},
  23. {Key: self, CreatedIndex: 2},
  24. {Key: "/1000/2", CreatedIndex: 3},
  25. {Key: "/1000/3", CreatedIndex: 4},
  26. {Key: "/1000/4", CreatedIndex: 5},
  27. },
  28. nil,
  29. 3,
  30. },
  31. {
  32. // self is in the size range
  33. client.Nodes{
  34. {Key: "/1000/_config/size", Value: "3", CreatedIndex: 1},
  35. {Key: "/1000/2", CreatedIndex: 2},
  36. {Key: "/1000/3", CreatedIndex: 3},
  37. {Key: self, CreatedIndex: 4},
  38. {Key: "/1000/4", CreatedIndex: 5},
  39. },
  40. nil,
  41. 3,
  42. },
  43. {
  44. // self is out of the size range
  45. client.Nodes{
  46. {Key: "/1000/_config/size", Value: "3", CreatedIndex: 1},
  47. {Key: "/1000/2", CreatedIndex: 2},
  48. {Key: "/1000/3", CreatedIndex: 3},
  49. {Key: "/1000/4", CreatedIndex: 4},
  50. {Key: self, CreatedIndex: 5},
  51. },
  52. ErrFullCluster,
  53. 3,
  54. },
  55. {
  56. // self is not in the cluster
  57. client.Nodes{
  58. {Key: "/1000/_config/size", Value: "3", CreatedIndex: 1},
  59. {Key: "/1000/2", CreatedIndex: 2},
  60. {Key: "/1000/3", CreatedIndex: 3},
  61. },
  62. nil,
  63. 3,
  64. },
  65. {
  66. client.Nodes{
  67. {Key: "/1000/_config/size", Value: "3", CreatedIndex: 1},
  68. {Key: "/1000/2", CreatedIndex: 2},
  69. {Key: "/1000/3", CreatedIndex: 3},
  70. {Key: "/1000/4", CreatedIndex: 4},
  71. },
  72. ErrFullCluster,
  73. 3,
  74. },
  75. {
  76. // bad size key
  77. client.Nodes{
  78. {Key: "/1000/_config/size", Value: "bad", CreatedIndex: 1},
  79. },
  80. ErrBadSizeKey,
  81. 0,
  82. },
  83. {
  84. // no size key
  85. client.Nodes{},
  86. ErrSizeNotFound,
  87. 0,
  88. },
  89. }
  90. for i, tt := range tests {
  91. rs := make([]*client.Response, 0)
  92. if len(tt.nodes) > 0 {
  93. rs = append(rs, &client.Response{Node: tt.nodes[0]})
  94. rs = append(rs, &client.Response{
  95. Node: &client.Node{
  96. Key: cluster,
  97. Nodes: tt.nodes,
  98. },
  99. })
  100. }
  101. c := &clientWithResp{rs: rs}
  102. d := discovery{cluster: cluster, id: 1, c: c}
  103. ns, size, err := d.checkCluster()
  104. if err != tt.werr {
  105. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  106. }
  107. if reflect.DeepEqual(ns, tt.nodes) {
  108. t.Errorf("#%d: nodes = %v, want %v", i, ns, tt.nodes)
  109. }
  110. if size != tt.wsize {
  111. t.Errorf("#%d: size = %v, want %d", i, size, tt.wsize)
  112. }
  113. }
  114. }
  115. func TestWaitNodes(t *testing.T) {
  116. all := client.Nodes{
  117. {Key: "/1000/1", CreatedIndex: 2},
  118. {Key: "/1000/2", CreatedIndex: 3},
  119. {Key: "/1000/3", CreatedIndex: 4},
  120. }
  121. tests := []struct {
  122. nodes client.Nodes
  123. size int
  124. rs []*client.Response
  125. werr error
  126. wall client.Nodes
  127. }{
  128. {
  129. all,
  130. 3,
  131. []*client.Response{},
  132. nil,
  133. all,
  134. },
  135. {
  136. all[:1],
  137. 3,
  138. []*client.Response{
  139. {Node: &client.Node{Key: "/1000/2", CreatedIndex: 3}},
  140. {Node: &client.Node{Key: "/1000/3", CreatedIndex: 4}},
  141. },
  142. nil,
  143. all,
  144. },
  145. {
  146. all[:2],
  147. 3,
  148. []*client.Response{
  149. {Node: &client.Node{Key: "/1000/3", CreatedIndex: 4}},
  150. },
  151. nil,
  152. all,
  153. },
  154. {
  155. append(all, &client.Node{Key: "/1000/4", CreatedIndex: 5}),
  156. 3,
  157. []*client.Response{
  158. {Node: &client.Node{Key: "/1000/3", CreatedIndex: 4}},
  159. },
  160. nil,
  161. all,
  162. },
  163. }
  164. for i, tt := range tests {
  165. c := &clientWithResp{nil, &watcherWithResp{tt.rs}}
  166. d := &discovery{cluster: "1000", c: c}
  167. g, err := d.waitNodes(tt.nodes, tt.size)
  168. if err != tt.werr {
  169. t.Errorf("#%d: err = %v, want %v", i, err, tt.werr)
  170. }
  171. if !reflect.DeepEqual(g, tt.wall) {
  172. t.Errorf("#%d: all = %v, want %v", i, g, tt.wall)
  173. }
  174. }
  175. }
  176. func TestCreateSelf(t *testing.T) {
  177. rs := []*client.Response{{Node: &client.Node{Key: "1000/1", CreatedIndex: 2}}}
  178. w := &watcherWithResp{rs}
  179. errw := &watcherWithErr{errors.New("watch err")}
  180. c := &clientWithResp{rs, w}
  181. errc := &clientWithErr{errors.New("create err"), w}
  182. errwc := &clientWithResp{rs, errw}
  183. tests := []struct {
  184. c client.Client
  185. werr error
  186. }{
  187. // no error
  188. {c, nil},
  189. // client.create returns an error
  190. {errc, errc.err},
  191. // watcher.next retuens an error
  192. {errwc, errw.err},
  193. }
  194. for i, tt := range tests {
  195. d := discovery{cluster: "1000", c: tt.c}
  196. if err := d.createSelf(); err != tt.werr {
  197. t.Errorf("#%d: err = %v, want %v", i, err, nil)
  198. }
  199. }
  200. }
  201. func TestNodesToCluster(t *testing.T) {
  202. nodes := client.Nodes{
  203. {Key: "/1000/1", Value: "1=1.1.1.1", CreatedIndex: 1},
  204. {Key: "/1000/2", Value: "2=2.2.2.2", CreatedIndex: 2},
  205. {Key: "/1000/3", Value: "3=3.3.3.3", CreatedIndex: 3},
  206. }
  207. w := "1=1.1.1.1,2=2.2.2.2,3=3.3.3.3"
  208. cluster := nodesToCluster(nodes)
  209. if !reflect.DeepEqual(cluster, w) {
  210. t.Errorf("cluster = %v, want %v", cluster, w)
  211. }
  212. }
  213. func TestSortableNodes(t *testing.T) {
  214. ns := client.Nodes{
  215. {CreatedIndex: 5},
  216. {CreatedIndex: 1},
  217. {CreatedIndex: 3},
  218. {CreatedIndex: 4},
  219. }
  220. // add some randomness
  221. for i := 0; i < 10000; i++ {
  222. ns = append(ns, &client.Node{CreatedIndex: uint64(rand.Int31())})
  223. }
  224. sns := sortableNodes{ns}
  225. sort.Sort(sns)
  226. cis := make([]int, 0)
  227. for _, n := range sns.Nodes {
  228. cis = append(cis, int(n.CreatedIndex))
  229. }
  230. if sort.IntsAreSorted(cis) != true {
  231. t.Errorf("isSorted = %v, want %v", sort.IntsAreSorted(cis), true)
  232. }
  233. cis = make([]int, 0)
  234. for _, n := range ns {
  235. cis = append(cis, int(n.CreatedIndex))
  236. }
  237. if sort.IntsAreSorted(cis) != true {
  238. t.Errorf("isSorted = %v, want %v", sort.IntsAreSorted(cis), true)
  239. }
  240. }
  241. type clientWithResp struct {
  242. rs []*client.Response
  243. w client.Watcher
  244. }
  245. func (c *clientWithResp) Create(key string, value string, ttl time.Duration) (*client.Response, error) {
  246. if len(c.rs) == 0 {
  247. return &client.Response{}, nil
  248. }
  249. r := c.rs[0]
  250. c.rs = c.rs[1:]
  251. return r, nil
  252. }
  253. func (c *clientWithResp) Get(key string) (*client.Response, error) {
  254. if len(c.rs) == 0 {
  255. return &client.Response{}, client.ErrKeyNoExist
  256. }
  257. r := c.rs[0]
  258. c.rs = c.rs[1:]
  259. return r, nil
  260. }
  261. func (c *clientWithResp) Watch(key string, waitIndex uint64) client.Watcher {
  262. return c.w
  263. }
  264. func (c *clientWithResp) RecursiveWatch(key string, waitIndex uint64) client.Watcher {
  265. return c.w
  266. }
  267. type clientWithErr struct {
  268. err error
  269. w client.Watcher
  270. }
  271. func (c *clientWithErr) Create(key string, value string, ttl time.Duration) (*client.Response, error) {
  272. return &client.Response{}, c.err
  273. }
  274. func (c *clientWithErr) Get(key string) (*client.Response, error) {
  275. return &client.Response{}, c.err
  276. }
  277. func (c *clientWithErr) Watch(key string, waitIndex uint64) client.Watcher {
  278. return c.w
  279. }
  280. func (c *clientWithErr) RecursiveWatch(key string, waitIndex uint64) client.Watcher {
  281. return c.w
  282. }
  283. type watcherWithResp struct {
  284. rs []*client.Response
  285. }
  286. func (w *watcherWithResp) Next() (*client.Response, error) {
  287. if len(w.rs) == 0 {
  288. return &client.Response{}, nil
  289. }
  290. r := w.rs[0]
  291. w.rs = w.rs[1:]
  292. return r, nil
  293. }
  294. type watcherWithErr struct {
  295. err error
  296. }
  297. func (w *watcherWithErr) Next() (*client.Response, error) {
  298. return &client.Response{}, w.err
  299. }