cluster_test.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*
  2. Copyright 2014 CoreOS, Inc.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package etcdserver
  14. import (
  15. "reflect"
  16. "testing"
  17. )
  18. func TestClusterAddSlice(t *testing.T) {
  19. tests := []struct {
  20. mems []Member
  21. want *Cluster
  22. }{
  23. {
  24. []Member{},
  25. &Cluster{},
  26. },
  27. {
  28. []Member{
  29. newTestMember(1, []string{"foo", "bar"}, "", nil),
  30. newTestMember(2, []string{"baz"}, "", nil),
  31. },
  32. &Cluster{
  33. 1: newTestMemberp(1, []string{"foo", "bar"}, "", nil),
  34. 2: newTestMemberp(2, []string{"baz"}, "", nil),
  35. },
  36. },
  37. }
  38. for i, tt := range tests {
  39. c := &Cluster{}
  40. if err := c.AddSlice(tt.mems); err != nil {
  41. t.Errorf("#%d: err=%#v, want nil", i, err)
  42. continue
  43. }
  44. if !reflect.DeepEqual(c, tt.want) {
  45. t.Errorf("#%d: c=%#v, want %#v", i, c, tt.want)
  46. }
  47. }
  48. }
  49. func TestClusterAddSliceBad(t *testing.T) {
  50. c := Cluster{
  51. 1: newTestMemberp(1, nil, "", nil),
  52. }
  53. if err := c.AddSlice([]Member{newTestMember(1, nil, "", nil)}); err == nil {
  54. t.Error("want err, but got nil")
  55. }
  56. }
  57. func TestClusterPick(t *testing.T) {
  58. cs := Cluster{
  59. 1: newTestMemberp(1, []string{"abc", "def", "ghi", "jkl", "mno", "pqr", "stu"}, "", nil),
  60. 2: newTestMemberp(2, []string{"xyz"}, "", nil),
  61. 3: newTestMemberp(3, []string{}, "", nil),
  62. }
  63. ids := map[string]bool{
  64. "abc": true,
  65. "def": true,
  66. "ghi": true,
  67. "jkl": true,
  68. "mno": true,
  69. "pqr": true,
  70. "stu": true,
  71. }
  72. for i := 0; i < 1000; i++ {
  73. a := cs.Pick(1)
  74. if !ids[a] {
  75. t.Errorf("returned ID %q not in expected range!", a)
  76. break
  77. }
  78. }
  79. if b := cs.Pick(2); b != "xyz" {
  80. t.Errorf("id=%q, want %q", b, "xyz")
  81. }
  82. if c := cs.Pick(3); c != "" {
  83. t.Errorf("id=%q, want %q", c, "")
  84. }
  85. if d := cs.Pick(4); d != "" {
  86. t.Errorf("id=%q, want %q", d, "")
  87. }
  88. }
  89. func TestClusterFind(t *testing.T) {
  90. tests := []struct {
  91. id uint64
  92. name string
  93. mems []Member
  94. match bool
  95. }{
  96. {
  97. 1,
  98. "node1",
  99. []Member{newTestMember(1, nil, "node1", nil)},
  100. true,
  101. },
  102. {
  103. 2,
  104. "foobar",
  105. []Member{},
  106. false,
  107. },
  108. {
  109. 2,
  110. "node2",
  111. []Member{newTestMember(1, nil, "node1", nil), newTestMember(2, nil, "node2", nil)},
  112. true,
  113. },
  114. {
  115. 3,
  116. "node3",
  117. []Member{newTestMember(1, nil, "node1", nil), newTestMember(2, nil, "node2", nil)},
  118. false,
  119. },
  120. }
  121. for i, tt := range tests {
  122. c := Cluster{}
  123. c.AddSlice(tt.mems)
  124. m := c.FindName(tt.name)
  125. if m == nil && !tt.match {
  126. continue
  127. }
  128. if m == nil && tt.match {
  129. t.Errorf("#%d: expected match got empty", i)
  130. }
  131. if m.Name != tt.name && tt.match {
  132. t.Errorf("#%d: got = %v, want %v", i, m.Name, tt.name)
  133. }
  134. }
  135. for i, tt := range tests {
  136. c := Cluster{}
  137. c.AddSlice(tt.mems)
  138. m := c.FindID(tt.id)
  139. if m == nil && !tt.match {
  140. continue
  141. }
  142. if m == nil && tt.match {
  143. t.Errorf("#%d: expected match got empty", i)
  144. }
  145. if m.ID != tt.id && tt.match {
  146. t.Errorf("#%d: got = %v, want %v", i, m.Name, tt.id)
  147. }
  148. }
  149. }
  150. func TestClusterSet(t *testing.T) {
  151. tests := []struct {
  152. f string
  153. mems []Member
  154. }{
  155. {
  156. "mem1=http://10.0.0.1:2379,mem1=http://128.193.4.20:2379,mem2=http://10.0.0.2:2379,default=http://127.0.0.1:2379",
  157. []Member{
  158. newTestMember(3736794188555456841, []string{"http://10.0.0.1:2379", "http://128.193.4.20:2379"}, "mem1", nil),
  159. newTestMember(5674507346857578431, []string{"http://10.0.0.2:2379"}, "mem2", nil),
  160. newTestMember(2676999861503984872, []string{"http://127.0.0.1:2379"}, "default", nil),
  161. },
  162. },
  163. }
  164. for i, tt := range tests {
  165. c := Cluster{}
  166. if err := c.AddSlice(tt.mems); err != nil {
  167. t.Error(err)
  168. }
  169. g := Cluster{}
  170. g.Set(tt.f)
  171. if g.String() != c.String() {
  172. t.Errorf("#%d: set = %v, want %v", i, g, c)
  173. }
  174. }
  175. }
  176. func TestClusterSetBad(t *testing.T) {
  177. tests := []string{
  178. // invalid URL
  179. "%^",
  180. // no URL defined for member
  181. "mem1=,mem2=http://128.193.4.20:2379,mem3=http://10.0.0.2:2379",
  182. "mem1,mem2=http://128.193.4.20:2379,mem3=http://10.0.0.2:2379",
  183. // TODO(philips): anyone know of a 64 bit sha1 hash collision
  184. // "06b2f82fd81b2c20=http://128.193.4.20:2379,02c60cb75083ceef=http://128.193.4.20:2379",
  185. }
  186. for i, tt := range tests {
  187. g := Cluster{}
  188. if err := g.Set(tt); err == nil {
  189. t.Errorf("#%d: set = %v, want err", i, tt)
  190. }
  191. }
  192. }
  193. func TestClusterIDs(t *testing.T) {
  194. cs := Cluster{}
  195. cs.AddSlice([]Member{
  196. newTestMember(1, nil, "", nil),
  197. newTestMember(4, nil, "", nil),
  198. newTestMember(100, nil, "", nil),
  199. })
  200. w := []uint64{1, 4, 100}
  201. g := cs.IDs()
  202. if !reflect.DeepEqual(w, g) {
  203. t.Errorf("IDs=%+v, want %+v", g, w)
  204. }
  205. }
  206. func TestClusterAddBad(t *testing.T) {
  207. // Should not be possible to add the same ID multiple times
  208. mems := []Member{
  209. newTestMember(1, nil, "mem1", nil),
  210. newTestMember(1, nil, "mem2", nil),
  211. }
  212. c := &Cluster{}
  213. c.Add(newTestMember(1, nil, "mem1", nil))
  214. for i, m := range mems {
  215. if err := c.Add(m); err == nil {
  216. t.Errorf("#%d: set = %v, want err", i, err)
  217. }
  218. }
  219. }
  220. func TestClusterPeerURLs(t *testing.T) {
  221. tests := []struct {
  222. mems []Member
  223. wurls []string
  224. }{
  225. // single peer with a single address
  226. {
  227. mems: []Member{
  228. newTestMember(1, []string{"http://192.0.2.1"}, "", nil),
  229. },
  230. wurls: []string{"http://192.0.2.1"},
  231. },
  232. // single peer with a single address with a port
  233. {
  234. mems: []Member{
  235. newTestMember(1, []string{"http://192.0.2.1:8001"}, "", nil),
  236. },
  237. wurls: []string{"http://192.0.2.1:8001"},
  238. },
  239. // several members explicitly unsorted
  240. {
  241. mems: []Member{
  242. newTestMember(2, []string{"http://192.0.2.3", "http://192.0.2.4"}, "", nil),
  243. newTestMember(3, []string{"http://192.0.2.5", "http://192.0.2.6"}, "", nil),
  244. newTestMember(1, []string{"http://192.0.2.1", "http://192.0.2.2"}, "", nil),
  245. },
  246. wurls: []string{"http://192.0.2.1", "http://192.0.2.2", "http://192.0.2.3", "http://192.0.2.4", "http://192.0.2.5", "http://192.0.2.6"},
  247. },
  248. // no members
  249. {
  250. mems: []Member{},
  251. wurls: []string{},
  252. },
  253. // peer with no peer urls
  254. {
  255. mems: []Member{
  256. newTestMember(3, []string{}, "", nil),
  257. },
  258. wurls: []string{},
  259. },
  260. }
  261. for i, tt := range tests {
  262. c := Cluster{}
  263. if err := c.AddSlice(tt.mems); err != nil {
  264. t.Errorf("AddSlice error: %v", err)
  265. continue
  266. }
  267. urls := c.PeerURLs()
  268. if !reflect.DeepEqual(urls, tt.wurls) {
  269. t.Errorf("#%d: PeerURLs = %v, want %v", i, urls, tt.wurls)
  270. }
  271. }
  272. }
  273. func TestClusterClientURLs(t *testing.T) {
  274. tests := []struct {
  275. mems []Member
  276. wurls []string
  277. }{
  278. // single peer with a single address
  279. {
  280. mems: []Member{
  281. newTestMember(1, nil, "", []string{"http://192.0.2.1"}),
  282. },
  283. wurls: []string{"http://192.0.2.1"},
  284. },
  285. // single peer with a single address with a port
  286. {
  287. mems: []Member{
  288. newTestMember(1, nil, "", []string{"http://192.0.2.1:8001"}),
  289. },
  290. wurls: []string{"http://192.0.2.1:8001"},
  291. },
  292. // several members explicitly unsorted
  293. {
  294. mems: []Member{
  295. newTestMember(2, nil, "", []string{"http://192.0.2.3", "http://192.0.2.4"}),
  296. newTestMember(3, nil, "", []string{"http://192.0.2.5", "http://192.0.2.6"}),
  297. newTestMember(1, nil, "", []string{"http://192.0.2.1", "http://192.0.2.2"}),
  298. },
  299. wurls: []string{"http://192.0.2.1", "http://192.0.2.2", "http://192.0.2.3", "http://192.0.2.4", "http://192.0.2.5", "http://192.0.2.6"},
  300. },
  301. // no members
  302. {
  303. mems: []Member{},
  304. wurls: []string{},
  305. },
  306. // peer with no client urls
  307. {
  308. mems: []Member{
  309. newTestMember(3, nil, "", []string{}),
  310. },
  311. wurls: []string{},
  312. },
  313. }
  314. for i, tt := range tests {
  315. c := Cluster{}
  316. if err := c.AddSlice(tt.mems); err != nil {
  317. t.Errorf("AddSlice error: %v", err)
  318. continue
  319. }
  320. urls := c.ClientURLs()
  321. if !reflect.DeepEqual(urls, tt.wurls) {
  322. t.Errorf("#%d: ClientURLs = %v, want %v", i, urls, tt.wurls)
  323. }
  324. }
  325. }