1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package membership
16
17 import (
18 "net/url"
19 "reflect"
20 "testing"
21 "time"
22
23 "go.etcd.io/etcd/client/pkg/v3/types"
24 )
25
26 func timeParse(value string) *time.Time {
27 t, err := time.Parse(time.RFC3339, value)
28 if err != nil {
29 panic(err)
30 }
31 return &t
32 }
33
34 func TestMemberTime(t *testing.T) {
35 tests := []struct {
36 mem *Member
37 id types.ID
38 }{
39 {NewMember("mem1", []url.URL{{Scheme: "http", Host: "10.0.0.8:2379"}}, "", nil), 14544069596553697298},
40
41 {NewMember("memfoo", []url.URL{{Scheme: "http", Host: "10.0.0.8:2379"}}, "", nil), 14544069596553697298},
42
43 {NewMember("mem1", []url.URL{{Scheme: "http", Host: "10.0.0.8:2379"}}, "", timeParse("1984-12-23T15:04:05Z")), 2448790162483548276},
44
45 {NewMember("mcm1", []url.URL{{Scheme: "http", Host: "10.0.0.8:2379"}}, "etcd", timeParse("1984-12-23T15:04:05Z")), 6973882743191604649},
46 {NewMember("mem1", []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}}, "", timeParse("1984-12-23T15:04:05Z")), 1466075294948436910},
47
48 {NewMember("mem1", []url.URL{{Scheme: "http", Host: "10.0.0.1:2379"}, {Scheme: "http", Host: "10.0.0.2:2379"}}, "", nil), 16552244735972308939},
49 {NewMember("mem1", []url.URL{{Scheme: "http", Host: "10.0.0.2:2379"}, {Scheme: "http", Host: "10.0.0.1:2379"}}, "", nil), 16552244735972308939},
50 }
51 for i, tt := range tests {
52 if tt.mem.ID != tt.id {
53 t.Errorf("#%d: mem.ID = %v, want %v", i, tt.mem.ID, tt.id)
54 }
55 }
56 }
57
58 func TestMemberPick(t *testing.T) {
59 tests := []struct {
60 memb *Member
61 urls map[string]bool
62 }{
63 {
64 newTestMember(1, []string{"abc", "def", "ghi", "jkl", "mno", "pqr", "stu"}, "", nil),
65 map[string]bool{
66 "abc": true,
67 "def": true,
68 "ghi": true,
69 "jkl": true,
70 "mno": true,
71 "pqr": true,
72 "stu": true,
73 },
74 },
75 {
76 newTestMember(2, []string{"xyz"}, "", nil),
77 map[string]bool{"xyz": true},
78 },
79 }
80 for i, tt := range tests {
81 for j := 0; j < 1000; j++ {
82 a := tt.memb.PickPeerURL()
83 if !tt.urls[a] {
84 t.Errorf("#%d: returned ID %q not in expected range!", i, a)
85 break
86 }
87 }
88 }
89 }
90
91 func TestMemberClone(t *testing.T) {
92 tests := []*Member{
93 newTestMember(1, nil, "abc", nil),
94 newTestMember(1, []string{"http://a"}, "abc", nil),
95 newTestMember(1, nil, "abc", []string{"http://b"}),
96 newTestMember(1, []string{"http://a"}, "abc", []string{"http://b"}),
97 }
98 for i, tt := range tests {
99 nm := tt.Clone()
100 if nm == tt {
101 t.Errorf("#%d: the pointers are the same, and clone doesn't happen", i)
102 }
103 if !reflect.DeepEqual(nm, tt) {
104 t.Errorf("#%d: member = %+v, want %+v", i, nm, tt)
105 }
106 }
107 }
108
109 func newTestMember(id uint64, peerURLs []string, name string, clientURLs []string) *Member {
110 return &Member{
111 ID: types.ID(id),
112 RaftAttributes: RaftAttributes{PeerURLs: peerURLs},
113 Attributes: Attributes{Name: name, ClientURLs: clientURLs},
114 }
115 }
116
117 func newTestMemberAsLearner(id uint64, peerURLs []string, name string, clientURLs []string) *Member {
118 return &Member{
119 ID: types.ID(id),
120 RaftAttributes: RaftAttributes{PeerURLs: peerURLs, IsLearner: true},
121 Attributes: Attributes{Name: name, ClientURLs: clientURLs},
122 }
123 }
124
View as plain text