OLD | NEW |
1 package presence_test | 1 package presence_test |
2 | 2 |
3 import ( | 3 import ( |
4 "fmt" | 4 "fmt" |
5 . "launchpad.net/gocheck" | 5 . "launchpad.net/gocheck" |
6 "launchpad.net/gozk/zookeeper" | 6 "launchpad.net/gozk/zookeeper" |
7 "launchpad.net/juju-core/juju/state/presence" | 7 "launchpad.net/juju-core/juju/state/presence" |
8 "testing" | 8 "testing" |
9 "time" | 9 "time" |
10 ) | 10 ) |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 119 |
120 // Watch for life, and check the watch doesn't fire early. | 120 // Watch for life, and check the watch doesn't fire early. |
121 alive, watch, err := presence.AliveW(s.zkConn, path) | 121 alive, watch, err := presence.AliveW(s.zkConn, path) |
122 c.Assert(err, IsNil) | 122 c.Assert(err, IsNil) |
123 c.Assert(alive, Equals, false) | 123 c.Assert(alive, Equals, false) |
124 assertNoChange(c, watch) | 124 assertNoChange(c, watch) |
125 | 125 |
126 // Start a Pinger, and check the watch fires. | 126 // Start a Pinger, and check the watch fires. |
127 p, err := presence.StartPinger(s.zkConn, path, period) | 127 p, err := presence.StartPinger(s.zkConn, path, period) |
128 c.Assert(err, IsNil) | 128 c.Assert(err, IsNil) |
129 defer p.Stop() | |
130 assertChange(c, watch, true) | 129 assertChange(c, watch, true) |
131 | 130 |
132 // Check that Alive agrees. | 131 // Check that Alive agrees. |
133 alive, err = presence.Alive(s.zkConn, path) | 132 alive, err = presence.Alive(s.zkConn, path) |
134 c.Assert(err, IsNil) | 133 c.Assert(err, IsNil) |
135 c.Assert(alive, Equals, true) | 134 c.Assert(alive, Equals, true) |
136 | 135 |
137 // Watch for life again, and check it doesn't change. | 136 // Watch for life again, and check it doesn't change. |
138 alive, watch, err = presence.AliveW(s.zkConn, path) | 137 alive, watch, err = presence.AliveW(s.zkConn, path) |
139 c.Assert(err, IsNil) | 138 c.Assert(err, IsNil) |
140 c.Assert(alive, Equals, true) | 139 c.Assert(alive, Equals, true) |
141 assertNoChange(c, watch) | 140 assertNoChange(c, watch) |
| 141 |
| 142 // Clean up. |
| 143 err = p.Kill() |
| 144 c.Assert(err, IsNil) |
142 } | 145 } |
143 | 146 |
144 func (s *PresenceSuite) TestKillPinger(c *C) { | 147 func (s *PresenceSuite) TestKillPinger(c *C) { |
145 // Start a Pinger and a watch, and check sanity. | 148 // Start a Pinger and a watch, and check sanity. |
146 p, err := presence.StartPinger(s.zkConn, path, period) | 149 p, err := presence.StartPinger(s.zkConn, path, period) |
147 c.Assert(err, IsNil) | 150 c.Assert(err, IsNil) |
148 alive, watch, err := presence.AliveW(s.zkConn, path) | 151 alive, watch, err := presence.AliveW(s.zkConn, path) |
149 c.Assert(err, IsNil) | 152 c.Assert(err, IsNil) |
150 c.Assert(alive, Equals, true) | 153 c.Assert(alive, Equals, true) |
151 assertNoChange(c, watch) | 154 assertNoChange(c, watch) |
152 | 155 |
153 // Kill the Pinger; check the watch fires and Alive agrees. | 156 // Kill the Pinger; check the watch fires and Alive agrees. |
154 » p.Kill() | 157 » err = p.Kill() |
| 158 » c.Assert(err, IsNil) |
155 assertChange(c, watch, false) | 159 assertChange(c, watch, false) |
156 alive, err = presence.Alive(s.zkConn, path) | 160 alive, err = presence.Alive(s.zkConn, path) |
157 c.Assert(err, IsNil) | 161 c.Assert(err, IsNil) |
158 c.Assert(alive, Equals, false) | 162 c.Assert(alive, Equals, false) |
159 | 163 |
160 // Check that the pinger's node was deleted. | 164 // Check that the pinger's node was deleted. |
161 stat, err := s.zkConn.Exists(path) | 165 stat, err := s.zkConn.Exists(path) |
162 c.Assert(err, IsNil) | 166 c.Assert(err, IsNil) |
163 c.Assert(stat, IsNil) | 167 c.Assert(stat, IsNil) |
164 } | 168 } |
165 | 169 |
166 func (s *PresenceSuite) TestStopPinger(c *C) { | 170 func (s *PresenceSuite) TestStopPinger(c *C) { |
167 // Start a Pinger and a watch, and check sanity. | 171 // Start a Pinger and a watch, and check sanity. |
168 p, err := presence.StartPinger(s.zkConn, path, period) | 172 p, err := presence.StartPinger(s.zkConn, path, period) |
169 c.Assert(err, IsNil) | 173 c.Assert(err, IsNil) |
170 alive, watch, err := presence.AliveW(s.zkConn, path) | 174 alive, watch, err := presence.AliveW(s.zkConn, path) |
171 c.Assert(err, IsNil) | 175 c.Assert(err, IsNil) |
172 c.Assert(alive, Equals, true) | 176 c.Assert(alive, Equals, true) |
173 assertNoChange(c, watch) | 177 assertNoChange(c, watch) |
174 | 178 |
175 // Stop the Pinger; check the watch fires and Alive agrees. | 179 // Stop the Pinger; check the watch fires and Alive agrees. |
176 » p.Stop() | 180 » err = p.Stop() |
| 181 » c.Assert(err, IsNil) |
177 assertChange(c, watch, false) | 182 assertChange(c, watch, false) |
178 alive, err = presence.Alive(s.zkConn, path) | 183 alive, err = presence.Alive(s.zkConn, path) |
179 c.Assert(err, IsNil) | 184 c.Assert(err, IsNil) |
180 c.Assert(alive, Equals, false) | 185 c.Assert(alive, Equals, false) |
181 | 186 |
182 // Check that the pinger's node is still present. | 187 // Check that the pinger's node is still present. |
183 stat, err := s.zkConn.Exists(path) | 188 stat, err := s.zkConn.Exists(path) |
184 c.Assert(err, IsNil) | 189 c.Assert(err, IsNil) |
185 c.Assert(stat, NotNil) | 190 c.Assert(stat, NotNil) |
186 } | 191 } |
187 | 192 |
188 func (s *PresenceSuite) TestWatchDeadnessChange(c *C) { | 193 func (s *PresenceSuite) TestWatchDeadnessChange(c *C) { |
189 // Create a stale node. | 194 // Create a stale node. |
190 p, err := presence.StartPinger(s.zkConn, path, period) | 195 p, err := presence.StartPinger(s.zkConn, path, period) |
191 c.Assert(err, IsNil) | 196 c.Assert(err, IsNil) |
192 » p.Stop() | 197 » err = p.Stop() |
| 198 » c.Assert(err, IsNil) |
193 time.Sleep(longEnough) | 199 time.Sleep(longEnough) |
194 | 200 |
195 // Start watching for liveness. | 201 // Start watching for liveness. |
196 alive, watch, err := presence.AliveW(s.zkConn, path) | 202 alive, watch, err := presence.AliveW(s.zkConn, path) |
197 c.Assert(err, IsNil) | 203 c.Assert(err, IsNil) |
198 c.Assert(alive, Equals, false) | 204 c.Assert(alive, Equals, false) |
199 | 205 |
200 // Delete the node and check the watch doesn't fire. | 206 // Delete the node and check the watch doesn't fire. |
201 err = s.zkConn.Delete(path, -1) | 207 err = s.zkConn.Delete(path, -1) |
202 c.Assert(err, IsNil) | 208 c.Assert(err, IsNil) |
203 assertNoChange(c, watch) | 209 assertNoChange(c, watch) |
204 | 210 |
205 // Start a new Pinger and check the watch does fire. | 211 // Start a new Pinger and check the watch does fire. |
206 p, err = presence.StartPinger(s.zkConn, path, period) | 212 p, err = presence.StartPinger(s.zkConn, path, period) |
207 c.Assert(err, IsNil) | 213 c.Assert(err, IsNil) |
208 defer p.Stop() | |
209 assertChange(c, watch, true) | 214 assertChange(c, watch, true) |
| 215 |
| 216 // Clean up. |
| 217 err = p.Kill() |
| 218 c.Assert(err, IsNil) |
210 } | 219 } |
211 | 220 |
212 func (s *PresenceSuite) TestBadData(c *C) { | 221 func (s *PresenceSuite) TestBadData(c *C) { |
213 // Create a node that contains inappropriate data. | 222 // Create a node that contains inappropriate data. |
214 _, err := s.zkConn.Create(path, "roflcopter", 0, zookeeper.WorldACL(zook
eeper.PERM_ALL)) | 223 _, err := s.zkConn.Create(path, "roflcopter", 0, zookeeper.WorldACL(zook
eeper.PERM_ALL)) |
215 c.Assert(err, IsNil) | 224 c.Assert(err, IsNil) |
216 | 225 |
217 // Check it is not interpreted as a presence node by Alive. | 226 // Check it is not interpreted as a presence node by Alive. |
218 _, err = presence.Alive(s.zkConn, path) | 227 _, err = presence.Alive(s.zkConn, path) |
219 c.Assert(err, ErrorMatches, `/presence presence node has bad data: "rofl
copter"`) | 228 c.Assert(err, ErrorMatches, `/presence presence node has bad data: "rofl
copter"`) |
220 | 229 |
221 // Check it is not interpreted as a presence node by Watch. | 230 // Check it is not interpreted as a presence node by Watch. |
222 _, watch, err := presence.AliveW(s.zkConn, path) | 231 _, watch, err := presence.AliveW(s.zkConn, path) |
223 c.Assert(watch, IsNil) | 232 c.Assert(watch, IsNil) |
224 c.Assert(err, ErrorMatches, `/presence presence node has bad data: "rofl
copter"`) | 233 c.Assert(err, ErrorMatches, `/presence presence node has bad data: "rofl
copter"`) |
225 } | 234 } |
226 | 235 |
227 func (s *PresenceSuite) TestDisconnectDeadWatch(c *C) { | 236 func (s *PresenceSuite) TestDisconnectDeadWatch(c *C) { |
228 // Create a target node. | 237 // Create a target node. |
229 p, err := presence.StartPinger(s.zkConn, path, period) | 238 p, err := presence.StartPinger(s.zkConn, path, period) |
230 c.Assert(err, IsNil) | 239 c.Assert(err, IsNil) |
231 » p.Stop() | 240 » err = p.Stop() |
| 241 » c.Assert(err, IsNil) |
232 | 242 |
233 // Start an alternate connection and ensure the node is stale. | 243 // Start an alternate connection and ensure the node is stale. |
234 altConn := s.connect(c) | 244 altConn := s.connect(c) |
235 time.Sleep(longEnough) | 245 time.Sleep(longEnough) |
236 | 246 |
237 // Start a watch using the alternate connection. | 247 // Start a watch using the alternate connection. |
238 alive, watch, err := presence.AliveW(altConn, path) | 248 alive, watch, err := presence.AliveW(altConn, path) |
239 c.Assert(err, IsNil) | 249 c.Assert(err, IsNil) |
240 c.Assert(alive, Equals, false) | 250 c.Assert(alive, Equals, false) |
241 | 251 |
(...skipping 13 matching lines...) Expand all Loading... |
255 | 265 |
256 // Kill the watch's connection and check it's alerted. | 266 // Kill the watch's connection and check it's alerted. |
257 altConn.Close() | 267 altConn.Close() |
258 assertClose(c, watch) | 268 assertClose(c, watch) |
259 } | 269 } |
260 | 270 |
261 func (s *PresenceSuite) TestDisconnectAliveWatch(c *C) { | 271 func (s *PresenceSuite) TestDisconnectAliveWatch(c *C) { |
262 // Start a Pinger on the main connection | 272 // Start a Pinger on the main connection |
263 p, err := presence.StartPinger(s.zkConn, path, period) | 273 p, err := presence.StartPinger(s.zkConn, path, period) |
264 c.Assert(err, IsNil) | 274 c.Assert(err, IsNil) |
265 defer p.Stop() | |
266 | 275 |
267 // Start watching on an alternate connection. | 276 // Start watching on an alternate connection. |
268 altConn := s.connect(c) | 277 altConn := s.connect(c) |
269 alive, watch, err := presence.AliveW(altConn, path) | 278 alive, watch, err := presence.AliveW(altConn, path) |
270 c.Assert(err, IsNil) | 279 c.Assert(err, IsNil) |
271 c.Assert(alive, Equals, true) | 280 c.Assert(alive, Equals, true) |
272 | 281 |
273 // Kill the watch's connection and check it's alerted. | 282 // Kill the watch's connection and check it's alerted. |
274 altConn.Close() | 283 altConn.Close() |
275 assertClose(c, watch) | 284 assertClose(c, watch) |
| 285 |
| 286 // Clean up. |
| 287 err = p.Kill() |
| 288 c.Assert(err, IsNil) |
276 } | 289 } |
277 | 290 |
278 func (s *PresenceSuite) TestDisconnectPinger(c *C) { | 291 func (s *PresenceSuite) TestDisconnectPinger(c *C) { |
279 // Start a Pinger on an alternate connection. | 292 // Start a Pinger on an alternate connection. |
280 altConn := s.connect(c) | 293 altConn := s.connect(c) |
281 p, err := presence.StartPinger(altConn, path, period) | 294 p, err := presence.StartPinger(altConn, path, period) |
282 c.Assert(err, IsNil) | 295 c.Assert(err, IsNil) |
283 defer p.Stop() | |
284 | 296 |
285 // Watch on the "main" connection. | 297 // Watch on the "main" connection. |
286 alive, watch, err := presence.AliveW(s.zkConn, path) | 298 alive, watch, err := presence.AliveW(s.zkConn, path) |
287 c.Assert(err, IsNil) | 299 c.Assert(err, IsNil) |
288 c.Assert(alive, Equals, true) | 300 c.Assert(alive, Equals, true) |
289 | 301 |
290 // Kill the pinger connection and check the watch notices. | 302 // Kill the pinger connection and check the watch notices. |
291 altConn.Close() | 303 altConn.Close() |
292 assertChange(c, watch, false) | 304 assertChange(c, watch, false) |
| 305 |
| 306 // Check the pinger already knows it broke. |
| 307 <-p.Dying() |
| 308 |
| 309 // Stop the pinger anyway; check we get an error. |
| 310 err = p.Stop() |
| 311 c.Assert(err, NotNil) |
293 } | 312 } |
294 | 313 |
295 func (s *PresenceSuite) TestWaitAlive(c *C) { | 314 func (s *PresenceSuite) TestWaitAlive(c *C) { |
296 err := presence.WaitAlive(s.zkConn, path, longEnough) | 315 err := presence.WaitAlive(s.zkConn, path, longEnough) |
297 c.Assert(err, ErrorMatches, "presence: still not alive after timeout") | 316 c.Assert(err, ErrorMatches, "presence: still not alive after timeout") |
298 | 317 |
299 » // Start a pinger with a short delay so that WaitAlive() detects it. | 318 » dying := make(chan struct{}) |
| 319 » dead := make(chan struct{}) |
| 320 |
| 321 » // Start a pinger with a short delay so that WaitAlive() has to wait. |
300 go func() { | 322 go func() { |
301 time.Sleep(period * 2) | 323 time.Sleep(period * 2) |
302 p, err := presence.StartPinger(s.zkConn, path, period) | 324 p, err := presence.StartPinger(s.zkConn, path, period) |
303 c.Assert(err, IsNil) | 325 c.Assert(err, IsNil) |
304 » » defer p.Kill() | 326 » » <-dying |
| 327 » » err = p.Kill() |
| 328 » » c.Assert(err, IsNil) |
| 329 » » close(dead) |
305 }() | 330 }() |
306 | 331 |
| 332 // Wait for, and check, liveness. |
307 err = presence.WaitAlive(s.zkConn, path, longEnough) | 333 err = presence.WaitAlive(s.zkConn, path, longEnough) |
308 c.Assert(err, IsNil) | 334 c.Assert(err, IsNil) |
| 335 close(dying) |
| 336 <-dead |
| 337 } |
309 | 338 |
310 » // Use alternative connection for closing test. | 339 func (s *PresenceSuite) TestDisconnectWaitAlive(c *C) { |
| 340 » // Start a new connection with a short lifespan. |
311 altConn := s.connect(c) | 341 altConn := s.connect(c) |
312 | |
313 go func() { | 342 go func() { |
314 time.Sleep(period * 2) | 343 time.Sleep(period * 2) |
315 altConn.Close() | 344 altConn.Close() |
316 }() | 345 }() |
317 | 346 |
318 » err = presence.WaitAlive(altConn, path, longEnough) | 347 » // Check that WaitAlive returns an appropriate error. |
| 348 » err := presence.WaitAlive(altConn, path, longEnough) |
319 c.Assert(err, ErrorMatches, "presence: channel closed while waiting") | 349 c.Assert(err, ErrorMatches, "presence: channel closed while waiting") |
320 } | 350 } |
OLD | NEW |