cluster_store_test.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. package etcdserver
  2. import (
  3. "reflect"
  4. "testing"
  5. "time"
  6. etcdErr "github.com/coreos/etcd/error"
  7. "github.com/coreos/etcd/store"
  8. )
  9. func TestClusterStoreAdd(t *testing.T) {
  10. st := &storeRecorder{}
  11. ps := &clusterStore{Store: st}
  12. ps.Add(newTestMember(1, nil, "node1", nil))
  13. wactions := []action{
  14. {
  15. name: "Create",
  16. params: []interface{}{
  17. machineKVPrefix + "1/raftAttributes",
  18. false,
  19. `{"PeerURLs":null}`,
  20. false,
  21. store.Permanent,
  22. },
  23. },
  24. {
  25. name: "Create",
  26. params: []interface{}{
  27. machineKVPrefix + "1/attributes",
  28. false,
  29. `{"Name":"node1","ClientURLs":null}`,
  30. false,
  31. store.Permanent,
  32. },
  33. },
  34. }
  35. if g := st.Action(); !reflect.DeepEqual(g, wactions) {
  36. t.Errorf("actions = %v, want %v", g, wactions)
  37. }
  38. }
  39. func TestClusterStoreGet(t *testing.T) {
  40. tests := []struct {
  41. mems []Member
  42. wmems []Member
  43. }{
  44. {
  45. []Member{newTestMember(1, nil, "node1", nil)},
  46. []Member{newTestMember(1, nil, "node1", nil)},
  47. },
  48. {
  49. []Member{},
  50. []Member{},
  51. },
  52. {
  53. []Member{
  54. newTestMember(1, nil, "node1", nil),
  55. newTestMember(2, nil, "node2", nil),
  56. },
  57. []Member{
  58. newTestMember(1, nil, "node1", nil),
  59. newTestMember(2, nil, "node2", nil),
  60. },
  61. },
  62. {
  63. []Member{
  64. newTestMember(2, nil, "node2", nil),
  65. newTestMember(1, nil, "node1", nil),
  66. },
  67. []Member{
  68. newTestMember(1, nil, "node1", nil),
  69. newTestMember(2, nil, "node2", nil),
  70. },
  71. },
  72. }
  73. for i, tt := range tests {
  74. cs := &clusterStore{Store: newGetAllStore()}
  75. for _, m := range tt.mems {
  76. cs.Add(m)
  77. }
  78. c := Cluster{}
  79. if err := c.AddSlice(tt.mems); err != nil {
  80. t.Fatal(err)
  81. }
  82. if g := cs.Get(); !reflect.DeepEqual(g, c) {
  83. t.Errorf("#%d: mems = %v, want %v", i, g, c)
  84. }
  85. }
  86. }
  87. func TestClusterStoreDelete(t *testing.T) {
  88. st := newStoreGetAllAndDeleteRecorder()
  89. cs := &clusterStore{Store: st}
  90. cs.Add(newTestMember(1, nil, "node1", nil))
  91. cs.Remove(1)
  92. wdeletes := []string{machineKVPrefix + "1"}
  93. if !reflect.DeepEqual(st.deletes, wdeletes) {
  94. t.Error("deletes = %v, want %v", st.deletes, wdeletes)
  95. }
  96. }
  97. func TestNodeToMemberFail(t *testing.T) {
  98. tests := []*store.NodeExtern{
  99. {Key: "/1234", Nodes: []*store.NodeExtern{
  100. {Key: "/1234/strange"},
  101. }},
  102. {Key: "/1234", Nodes: []*store.NodeExtern{
  103. {Key: "/1234/dynamic", Value: stringp("garbage")},
  104. }},
  105. {Key: "/1234", Nodes: []*store.NodeExtern{
  106. {Key: "/1234/dynamic", Value: stringp(`{"PeerURLs":null}`)},
  107. }},
  108. {Key: "/1234", Nodes: []*store.NodeExtern{
  109. {Key: "/1234/dynamic", Value: stringp(`{"PeerURLs":null}`)},
  110. {Key: "/1234/strange"},
  111. }},
  112. {Key: "/1234", Nodes: []*store.NodeExtern{
  113. {Key: "/1234/dynamic", Value: stringp(`{"PeerURLs":null}`)},
  114. {Key: "/1234/static", Value: stringp("garbage")},
  115. }},
  116. {Key: "/1234", Nodes: []*store.NodeExtern{
  117. {Key: "/1234/dynamic", Value: stringp(`{"PeerURLs":null}`)},
  118. {Key: "/1234/static", Value: stringp(`{"Name":"node1","ClientURLs":null}`)},
  119. {Key: "/1234/strange"},
  120. }},
  121. }
  122. for i, tt := range tests {
  123. if _, err := nodeToMember(tt); err == nil {
  124. t.Errorf("#%d: unexpected nil error", i)
  125. }
  126. }
  127. }
  128. func TestNodeToMember(t *testing.T) {
  129. n := &store.NodeExtern{Key: "/1234", Nodes: []*store.NodeExtern{
  130. {Key: "/1234/attributes", Value: stringp(`{"Name":"node1","ClientURLs":null}`)},
  131. {Key: "/1234/raftAttributes", Value: stringp(`{"PeerURLs":null}`)},
  132. }}
  133. wm := Member{ID: 0x1234, RaftAttributes: RaftAttributes{}, Attributes: Attributes{Name: "node1"}}
  134. m, err := nodeToMember(n)
  135. if err != nil {
  136. t.Fatalf("unexpected nodeToMember error: %v", err)
  137. }
  138. if !reflect.DeepEqual(m, wm) {
  139. t.Errorf("member = %+v, want %+v", m, wm)
  140. }
  141. }
  142. // simpleStore implements basic create and get.
  143. type simpleStore struct {
  144. storeRecorder
  145. st map[string]string
  146. }
  147. func (s *simpleStore) Create(key string, _ bool, value string, _ bool, _ time.Time) (*store.Event, error) {
  148. if s.st == nil {
  149. s.st = make(map[string]string)
  150. }
  151. s.st[key] = value
  152. return nil, nil
  153. }
  154. func (s *simpleStore) Get(key string, _, _ bool) (*store.Event, error) {
  155. val, ok := s.st[key]
  156. if !ok {
  157. return nil, etcdErr.NewError(etcdErr.EcodeKeyNotFound, "", 0)
  158. }
  159. ev := &store.Event{Node: &store.NodeExtern{Key: key, Value: stringp(val)}}
  160. return ev, nil
  161. }
  162. // getAllStore embeds simpleStore, and makes Get return all keys sorted.
  163. // It uses real store because it uses lots of logic in store and is not easy
  164. // to mock.
  165. // TODO: use mock one to do testing
  166. type getAllStore struct {
  167. store.Store
  168. }
  169. func newGetAllStore() *getAllStore {
  170. return &getAllStore{store.New()}
  171. }
  172. type storeGetAllAndDeleteRecorder struct {
  173. *getAllStore
  174. deletes []string
  175. }
  176. func newStoreGetAllAndDeleteRecorder() *storeGetAllAndDeleteRecorder {
  177. return &storeGetAllAndDeleteRecorder{getAllStore: newGetAllStore()}
  178. }
  179. func (s *storeGetAllAndDeleteRecorder) Delete(key string, _, _ bool) (*store.Event, error) {
  180. s.deletes = append(s.deletes, key)
  181. return nil, nil
  182. }
  183. func newTestMember(id uint64, peerURLs []string, name string, clientURLs []string) Member {
  184. return Member{
  185. ID: id,
  186. RaftAttributes: RaftAttributes{PeerURLs: peerURLs},
  187. Attributes: Attributes{Name: name, ClientURLs: clientURLs},
  188. }
  189. }
  190. func newTestMemberp(id uint64, peerURLs []string, name string, clientURLs []string) *Member {
  191. m := newTestMember(id, peerURLs, name, clientURLs)
  192. return &m
  193. }