loadbalancer/zk: test cleanups
Peter Bourgon
8 years ago
5 | 5 | "time" |
6 | 6 | |
7 | 7 | stdzk "github.com/samuel/go-zookeeper/zk" |
8 | ||
9 | "github.com/go-kit/kit/log" | |
8 | 10 | ) |
9 | 11 | |
10 | 12 | func TestNewClient(t *testing.T) { |
17 | 19 | |
18 | 20 | c, err := NewClient( |
19 | 21 | []string{"FailThisInvalidHost!!!"}, |
20 | logger, | |
22 | log.NewNopLogger(), | |
21 | 23 | ) |
22 | ||
23 | time.Sleep(1 * time.Millisecond) | |
24 | 24 | if err == nil { |
25 | 25 | t.Errorf("expected error, got nil") |
26 | 26 | } |
27 | ||
27 | 28 | hasFired := false |
28 | 29 | calledEventHandler := make(chan struct{}) |
29 | 30 | eventHandler := func(event stdzk.Event) { |
33 | 34 | close(calledEventHandler) |
34 | 35 | } |
35 | 36 | } |
37 | ||
36 | 38 | c, err = NewClient( |
37 | 39 | []string{"localhost"}, |
38 | logger, | |
40 | log.NewNopLogger(), | |
39 | 41 | ACL(acl), |
40 | 42 | ConnectTimeout(connectTimeout), |
41 | 43 | SessionTimeout(sessionTimeout), |
46 | 48 | t.Fatal(err) |
47 | 49 | } |
48 | 50 | defer c.Stop() |
51 | ||
49 | 52 | clientImpl, ok := c.(*client) |
50 | 53 | if !ok { |
51 | t.Errorf("retrieved incorrect Client implementation") | |
54 | t.Fatal("retrieved incorrect Client implementation") | |
52 | 55 | } |
53 | 56 | if want, have := acl, clientImpl.acl; want[0] != have[0] { |
54 | 57 | t.Errorf("want %+v, have %+v", want, have) |
71 | 74 | } |
72 | 75 | |
73 | 76 | func TestOptions(t *testing.T) { |
74 | _, err := NewClient([]string{"localhost"}, logger, Credentials("valid", "credentials")) | |
77 | _, err := NewClient([]string{"localhost"}, log.NewNopLogger(), Credentials("valid", "credentials")) | |
75 | 78 | if err != nil && err != stdzk.ErrNoServer { |
76 | 79 | t.Errorf("unexpected error: %v", err) |
77 | 80 | } |
78 | 81 | |
79 | _, err = NewClient([]string{"localhost"}, logger, Credentials("nopass", "")) | |
82 | _, err = NewClient([]string{"localhost"}, log.NewNopLogger(), Credentials("nopass", "")) | |
80 | 83 | if want, have := err, ErrInvalidCredentials; want != have { |
81 | 84 | t.Errorf("want %v, have %v", want, have) |
82 | 85 | } |
83 | 86 | |
84 | _, err = NewClient([]string{"localhost"}, logger, ConnectTimeout(0)) | |
87 | _, err = NewClient([]string{"localhost"}, log.NewNopLogger(), ConnectTimeout(0)) | |
85 | 88 | if err == nil { |
86 | 89 | t.Errorf("expected connect timeout error") |
87 | 90 | } |
88 | 91 | |
89 | _, err = NewClient([]string{"localhost"}, logger, SessionTimeout(0)) | |
92 | _, err = NewClient([]string{"localhost"}, log.NewNopLogger(), SessionTimeout(0)) | |
90 | 93 | if err == nil { |
91 | 94 | t.Errorf("expected connect timeout error") |
92 | 95 | } |
95 | 98 | func TestCreateParentNodes(t *testing.T) { |
96 | 99 | payload := [][]byte{[]byte("Payload"), []byte("Test")} |
97 | 100 | |
98 | c, err := NewClient([]string{"localhost:65500"}, logger) | |
101 | c, err := NewClient([]string{"localhost:65500"}, log.NewNopLogger()) | |
99 | 102 | if err != nil { |
100 | 103 | t.Errorf("unexpected error: %v", err) |
101 | 104 | } |
102 | 105 | if c == nil { |
103 | t.Fatalf("expected new Client, got nil") | |
106 | t.Fatal("expected new Client, got nil") | |
104 | 107 | } |
105 | p, err := NewPublisher(c, "/validpath", newFactory(""), logger) | |
108 | ||
109 | p, err := NewPublisher(c, "/validpath", newFactory(""), log.NewNopLogger()) | |
106 | 110 | if err != stdzk.ErrNoServer { |
107 | 111 | t.Errorf("unexpected error: %v", err) |
108 | 112 | } |
109 | 113 | if p != nil { |
110 | t.Errorf("expected failed new Publisher") | |
114 | t.Error("expected failed new Publisher") | |
111 | 115 | } |
112 | p, err = NewPublisher(c, "invalidpath", newFactory(""), logger) | |
116 | ||
117 | p, err = NewPublisher(c, "invalidpath", newFactory(""), log.NewNopLogger()) | |
113 | 118 | if err != stdzk.ErrInvalidPath { |
114 | 119 | t.Errorf("unexpected error: %v", err) |
115 | 120 | } |
117 | 122 | if err != stdzk.ErrNoServer { |
118 | 123 | t.Errorf("unexpected error: %v", err) |
119 | 124 | } |
120 | // stopping Client | |
125 | ||
121 | 126 | c.Stop() |
127 | ||
122 | 128 | err = c.CreateParentNodes("/validpath") |
123 | 129 | if err != ErrClientClosed { |
124 | 130 | t.Errorf("unexpected error: %v", err) |
125 | 131 | } |
126 | p, err = NewPublisher(c, "/validpath", newFactory(""), logger) | |
132 | ||
133 | p, err = NewPublisher(c, "/validpath", newFactory(""), log.NewNopLogger()) | |
127 | 134 | if err != ErrClientClosed { |
128 | 135 | t.Errorf("unexpected error: %v", err) |
129 | 136 | } |
130 | 137 | if p != nil { |
131 | t.Errorf("expected failed new Publisher") | |
138 | t.Error("expected failed new Publisher") | |
132 | 139 | } |
133 | c, err = NewClient([]string{"localhost:65500"}, logger, Payload(payload)) | |
140 | ||
141 | c, err = NewClient([]string{"localhost:65500"}, log.NewNopLogger(), Payload(payload)) | |
134 | 142 | if err != nil { |
135 | 143 | t.Errorf("unexpected error: %v", err) |
136 | 144 | } |
137 | 145 | if c == nil { |
138 | t.Fatalf("expected new Client, got nil") | |
146 | t.Fatal("expected new Client, got nil") | |
139 | 147 | } |
140 | p, err = NewPublisher(c, "/validpath", newFactory(""), logger) | |
148 | ||
149 | p, err = NewPublisher(c, "/validpath", newFactory(""), log.NewNopLogger()) | |
141 | 150 | if err != stdzk.ErrNoServer { |
142 | 151 | t.Errorf("unexpected error: %v", err) |
143 | 152 | } |
144 | 153 | if p != nil { |
145 | t.Errorf("expected failed new Publisher") | |
154 | t.Error("expected failed new Publisher") | |
146 | 155 | } |
147 | 156 | } |
0 | 0 | package zk |
1 | 1 | |
2 | 2 | import ( |
3 | "errors" | |
4 | "fmt" | |
5 | "io" | |
6 | "sync" | |
7 | 3 | "testing" |
8 | 4 | "time" |
9 | ||
10 | "golang.org/x/net/context" | |
11 | ||
12 | "github.com/go-kit/kit/endpoint" | |
13 | "github.com/go-kit/kit/loadbalancer" | |
14 | "github.com/go-kit/kit/log" | |
15 | "github.com/samuel/go-zookeeper/zk" | |
16 | ) | |
17 | ||
18 | var ( | |
19 | path = "/gokit.test/service.name" | |
20 | e = func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil } | |
21 | logger = log.NewNopLogger() | |
22 | 5 | ) |
23 | 6 | |
24 | 7 | func TestPublisher(t *testing.T) { |
130 | 113 | t.Error("expected publisher not to be created") |
131 | 114 | } |
132 | 115 | } |
133 | ||
134 | type fakeClient struct { | |
135 | mtx sync.Mutex | |
136 | ch chan zk.Event | |
137 | responses map[string]string | |
138 | result bool | |
139 | } | |
140 | ||
141 | func newFakeClient() *fakeClient { | |
142 | return &fakeClient{ | |
143 | ch: make(chan zk.Event, 5), | |
144 | responses: make(map[string]string), | |
145 | result: true, | |
146 | } | |
147 | } | |
148 | ||
149 | func (c *fakeClient) CreateParentNodes(path string) error { | |
150 | if path == "BadPath" { | |
151 | return errors.New("Dummy Error") | |
152 | } | |
153 | return nil | |
154 | } | |
155 | ||
156 | func (c *fakeClient) GetEntries(path string) ([]string, <-chan zk.Event, error) { | |
157 | c.mtx.Lock() | |
158 | defer c.mtx.Unlock() | |
159 | if c.result == false { | |
160 | c.result = true | |
161 | return []string{}, c.ch, errors.New("Dummy Error") | |
162 | } | |
163 | responses := []string{} | |
164 | for _, data := range c.responses { | |
165 | responses = append(responses, data) | |
166 | } | |
167 | return responses, c.ch, nil | |
168 | } | |
169 | ||
170 | func (c *fakeClient) AddService(node, data string) { | |
171 | c.mtx.Lock() | |
172 | defer c.mtx.Unlock() | |
173 | c.responses[node] = data | |
174 | c.ch <- zk.Event{} | |
175 | } | |
176 | ||
177 | func (c *fakeClient) RemoveService(node string) { | |
178 | c.mtx.Lock() | |
179 | defer c.mtx.Unlock() | |
180 | delete(c.responses, node) | |
181 | c.ch <- zk.Event{} | |
182 | } | |
183 | ||
184 | func (c *fakeClient) SendErrorOnWatch() { | |
185 | c.mtx.Lock() | |
186 | defer c.mtx.Unlock() | |
187 | c.result = false | |
188 | c.ch <- zk.Event{} | |
189 | } | |
190 | ||
191 | func (c *fakeClient) ErrorIsConsumed(t time.Duration) error { | |
192 | timeout := time.After(t) | |
193 | for { | |
194 | select { | |
195 | case <-timeout: | |
196 | return fmt.Errorf("expected error not consumed after timeout %s", t.String()) | |
197 | default: | |
198 | c.mtx.Lock() | |
199 | if c.result == false { | |
200 | c.mtx.Unlock() | |
201 | return nil | |
202 | } | |
203 | c.mtx.Unlock() | |
204 | } | |
205 | } | |
206 | } | |
207 | ||
208 | func (c *fakeClient) Stop() {} | |
209 | ||
210 | func newFactory(fakeError string) loadbalancer.Factory { | |
211 | return func(instance string) (endpoint.Endpoint, io.Closer, error) { | |
212 | if fakeError == instance { | |
213 | return nil, nil, errors.New(fakeError) | |
214 | } | |
215 | return e, nil, nil | |
216 | } | |
217 | } | |
218 | ||
219 | func asyncTest(timeout time.Duration, want int, p *Publisher) (err error) { | |
220 | var endpoints []endpoint.Endpoint | |
221 | // want can never be -1 | |
222 | have := -1 | |
223 | t := time.After(timeout) | |
224 | for { | |
225 | select { | |
226 | case <-t: | |
227 | return fmt.Errorf("want %d, have %d after timeout %s", want, have, timeout.String()) | |
228 | default: | |
229 | endpoints, err = p.Endpoints() | |
230 | have = len(endpoints) | |
231 | if err != nil || want == have { | |
232 | return | |
233 | } | |
234 | time.Sleep(time.Millisecond) | |
235 | } | |
236 | } | |
237 | } |
0 | package zk | |
1 | ||
2 | import ( | |
3 | "errors" | |
4 | "fmt" | |
5 | "io" | |
6 | "sync" | |
7 | "time" | |
8 | ||
9 | "github.com/samuel/go-zookeeper/zk" | |
10 | "golang.org/x/net/context" | |
11 | ||
12 | "github.com/go-kit/kit/endpoint" | |
13 | "github.com/go-kit/kit/loadbalancer" | |
14 | "github.com/go-kit/kit/log" | |
15 | ) | |
16 | ||
17 | var ( | |
18 | path = "/gokit.test/service.name" | |
19 | e = func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil } | |
20 | logger = log.NewNopLogger() | |
21 | ) | |
22 | ||
23 | type fakeClient struct { | |
24 | mtx sync.Mutex | |
25 | ch chan zk.Event | |
26 | responses map[string]string | |
27 | result bool | |
28 | } | |
29 | ||
30 | func newFakeClient() *fakeClient { | |
31 | return &fakeClient{ | |
32 | ch: make(chan zk.Event, 5), | |
33 | responses: make(map[string]string), | |
34 | result: true, | |
35 | } | |
36 | } | |
37 | ||
38 | func (c *fakeClient) CreateParentNodes(path string) error { | |
39 | if path == "BadPath" { | |
40 | return errors.New("Dummy Error") | |
41 | } | |
42 | return nil | |
43 | } | |
44 | ||
45 | func (c *fakeClient) GetEntries(path string) ([]string, <-chan zk.Event, error) { | |
46 | c.mtx.Lock() | |
47 | defer c.mtx.Unlock() | |
48 | if c.result == false { | |
49 | c.result = true | |
50 | return []string{}, c.ch, errors.New("Dummy Error") | |
51 | } | |
52 | responses := []string{} | |
53 | for _, data := range c.responses { | |
54 | responses = append(responses, data) | |
55 | } | |
56 | return responses, c.ch, nil | |
57 | } | |
58 | ||
59 | func (c *fakeClient) AddService(node, data string) { | |
60 | c.mtx.Lock() | |
61 | defer c.mtx.Unlock() | |
62 | c.responses[node] = data | |
63 | c.ch <- zk.Event{} | |
64 | } | |
65 | ||
66 | func (c *fakeClient) RemoveService(node string) { | |
67 | c.mtx.Lock() | |
68 | defer c.mtx.Unlock() | |
69 | delete(c.responses, node) | |
70 | c.ch <- zk.Event{} | |
71 | } | |
72 | ||
73 | func (c *fakeClient) SendErrorOnWatch() { | |
74 | c.mtx.Lock() | |
75 | defer c.mtx.Unlock() | |
76 | c.result = false | |
77 | c.ch <- zk.Event{} | |
78 | } | |
79 | ||
80 | func (c *fakeClient) ErrorIsConsumed(t time.Duration) error { | |
81 | timeout := time.After(t) | |
82 | for { | |
83 | select { | |
84 | case <-timeout: | |
85 | return fmt.Errorf("expected error not consumed after timeout %s", t.String()) | |
86 | default: | |
87 | c.mtx.Lock() | |
88 | if c.result == false { | |
89 | c.mtx.Unlock() | |
90 | return nil | |
91 | } | |
92 | c.mtx.Unlock() | |
93 | } | |
94 | } | |
95 | } | |
96 | ||
97 | func (c *fakeClient) Stop() {} | |
98 | ||
99 | func newFactory(fakeError string) loadbalancer.Factory { | |
100 | return func(instance string) (endpoint.Endpoint, io.Closer, error) { | |
101 | if fakeError == instance { | |
102 | return nil, nil, errors.New(fakeError) | |
103 | } | |
104 | return e, nil, nil | |
105 | } | |
106 | } | |
107 | ||
108 | func asyncTest(timeout time.Duration, want int, p *Publisher) (err error) { | |
109 | var endpoints []endpoint.Endpoint | |
110 | // want can never be -1 | |
111 | have := -1 | |
112 | t := time.After(timeout) | |
113 | for { | |
114 | select { | |
115 | case <-t: | |
116 | return fmt.Errorf("want %d, have %d after timeout %s", want, have, timeout.String()) | |
117 | default: | |
118 | endpoints, err = p.Endpoints() | |
119 | have = len(endpoints) | |
120 | if err != nil || want == have { | |
121 | return | |
122 | } | |
123 | time.Sleep(time.Millisecond) | |
124 | } | |
125 | } | |
126 | } |