Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(167)

Delta Between Two Patch Sets: state/internal_test.go

Issue 5786051: Move ZK test server setup into its own package
Left Patch Set: Move ZK test server setup into its own package Created 12 years ago
Right Patch Set: Move ZK test server setup into its own package Created 12 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « state/export_test.go ('k') | state/state_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // launchpad.net/juju/go/state
2 //
3 // Copyright (c) 2011-2012 Canonical Ltd.
4 package state
5
6 import (
7 . "launchpad.net/gocheck"
8 "launchpad.net/goyaml"
9 "launchpad.net/gozk/zookeeper"
10 )
11
12 type TopologySuite struct {
13 zkServer *zookeeper.Server
14 zkTestRoot string
15 zkTestPort int
16 zkAddr string
17 zkConn *zookeeper.Conn
1 t *topology 18 t *topology
2 } 19 }
3 20
4 var _ = Suite(&TopologySuite{}) 21 var _ = Suite(&TopologySuite{})
22 var TestingZkAddr string
5 23
6 func (s *TopologySuite) SetUpTest(c *C) { 24 func (s *TopologySuite) SetUpTest(c *C) {
7 // Connect the server. 25 // Connect the server.
26 st, err := Open(&Info{
27 Addrs: []string{TestingZkAddr},
28 })
29 c.Assert(err, IsNil)
30 s.zkConn = ZkConn(st)
31 // Read the toplogy.
32 s.t, err = readTopology(s.zkConn)
33 c.Assert(err, IsNil)
34 }
35
36 func (s *TopologySuite) TearDownTest(c *C) {
37 // Delete possible nodes, ignore errors.
38 zkRemoveTree(s.zkConn, "/topology")
39 s.zkConn.Close()
40 }
41
42 func (s TopologySuite) TestAddMachine(c *C) {
43 // Check that adding machines works correctly.
44 err := s.t.AddMachine("m-0")
45 c.Assert(err, IsNil)
46 err = s.t.AddMachine("m-1")
47 c.Assert(err, IsNil)
48 keys := s.t.MachineKeys()
49 c.Assert(keys, DeepEquals, []string{"m-0", "m-1"})
50 }
51
52 func (s TopologySuite) TestAddDuplicatedMachine(c *C) {
53 // Check that adding a duplicated machine by key fails.
54 err := s.t.AddMachine("m-0")
55 c.Assert(err, IsNil)
56 err = s.t.AddMachine("m-0")
57 c.Assert(err, ErrorMatches, `attempted to add duplicated machine "m-0"`)
58 }
59
60 func (s TopologySuite) TestRemoveMachine(c *C) {
61 // Check that removing machines works correctly.
62 err := s.t.AddMachine("m-0")
63 c.Assert(err, IsNil)
64 err = s.t.AddMachine("m-1")
65 c.Assert(err, IsNil)
66 // Add non-assigned unit. This tests that the logic of
67 // checking for assigned units works correctly too.
68 err = s.t.AddService("s-0", "wordpress")
69 c.Assert(err, IsNil)
70 _, err = s.t.AddUnit("s-0", "u-0")
71 c.Assert(err, IsNil)
72
73 err = s.t.RemoveMachine("m-0")
74 c.Assert(err, IsNil)
75
76 found := s.t.HasMachine("m-0")
77 c.Assert(found, Equals, false)
78 found = s.t.HasMachine("m-1")
79 c.Assert(found, Equals, true)
80 }
81
82 func (s TopologySuite) TestRemoveNonExistentMachine(c *C) {
83 // Check that the removing of a non-existent machine fails.
84 err := s.t.RemoveMachine("m-0")
85 c.Assert(err, ErrorMatches, `machine with key "m-0" not found`)
86 }
87
88 func (s TopologySuite) TestRemoveMachineWithAssignedUnits(c *C) {
89 // Check that a machine can't be removed when it has assigned units.
90 err := s.t.AddMachine("m-0")
91 c.Assert(err, IsNil)
92 err = s.t.AddService("s-0", "wordpress")
93 c.Assert(err, IsNil)
94 _, err = s.t.AddUnit("s-0", "u-0")
95 c.Assert(err, IsNil)
96 _, err = s.t.AddUnit("s-0", "u-1")
97 c.Assert(err, IsNil)
98 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0")
99 c.Assert(err, IsNil)
100 err = s.t.RemoveMachine("m-0")
101 c.Assert(err, ErrorMatches, `can't remove machine "m-0" while units ared assigned`)
102 }
103
104 func (s TopologySuite) TestMachineHasUnits(c *C) {
105 // Check various ways a machine might or might not be assigned
106 // to a unit.
107 err := s.t.AddMachine("m-0")
108 c.Assert(err, IsNil)
109 err = s.t.AddMachine("m-1")
110 c.Assert(err, IsNil)
111 err = s.t.AddService("s-0", "wordpress")
112 c.Assert(err, IsNil)
113 _, err = s.t.AddUnit("s-0", "u-0")
114 c.Assert(err, IsNil)
115 _, err = s.t.AddUnit("s-0", "u-1")
116 c.Assert(err, IsNil)
117 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0")
118 c.Assert(err, IsNil)
119 ok, err := s.t.MachineHasUnits("m-0")
120 c.Assert(err, IsNil)
121 c.Assert(ok, Equals, true)
122 ok, err = s.t.MachineHasUnits("m-1")
123 c.Assert(err, IsNil)
124 c.Assert(ok, Equals, false)
125 ok, err = s.t.MachineHasUnits("m-99")
126 c.Assert(err, ErrorMatches, `machine with key "m-99" not found`)
127 }
128
129 func (s TopologySuite) TestHasMachine(c *C) {
130 // Check that the test for a machine works correctly.
131 found := s.t.HasMachine("m-0")
132 c.Assert(found, Equals, false)
133 err := s.t.AddMachine("m-0")
134 c.Assert(err, IsNil)
135 found = s.t.HasMachine("m-0")
136 c.Assert(found, Equals, true)
137 found = s.t.HasMachine("m-1")
138 c.Assert(found, Equals, false)
139 }
140
141 func (s TopologySuite) TestMachineKeys(c *C) {
142 // Check that the retrieval of all services keys works correctly.
143 keys := s.t.MachineKeys()
144 c.Assert(keys, DeepEquals, []string{})
145 err := s.t.AddMachine("m-0")
146 c.Assert(err, IsNil)
147 err = s.t.AddMachine("m-1")
148 c.Assert(err, IsNil)
149 keys = s.t.MachineKeys()
150 c.Assert(keys, DeepEquals, []string{"m-0", "m-1"})
151 }
152
153 func (s TopologySuite) TestAddService(c *C) {
154 // Check that adding services works correctly.
155 c.Assert(s.t.HasService("s-0"), Equals, false)
156 err := s.t.AddService("s-0", "wordpress")
157 c.Assert(err, IsNil)
158 err = s.t.AddService("s-1", "mysql")
159 c.Assert(err, IsNil)
160 c.Assert(s.t.HasService("s-0"), Equals, true)
161 c.Assert(s.t.HasService("s-1"), Equals, true)
162 }
163
164 func (s TopologySuite) TestAddDuplicatedService(c *C) {
165 // Check that adding a duplicated service by key or name fails.
166 err := s.t.AddService("s-0", "wordpress")
167 c.Assert(err, IsNil)
168 err = s.t.AddService("s-0", "mysql")
169 c.Assert(err, ErrorMatches, `attempted to add duplicated service "s-0"`)
170 err = s.t.AddService("s-1", "wordpress")
171 c.Assert(err, ErrorMatches, `service name "wordpress" already in use`)
172 }
173
174 func (s TopologySuite) TestHasService(c *C) {
175 // Check that the test for a service works correctly.
176 found := s.t.HasService("s-0")
177 c.Assert(found, Equals, false)
178 err := s.t.AddService("s-0", "wordpress")
179 c.Assert(err, IsNil)
180 found = s.t.HasService("s-0")
181 c.Assert(found, Equals, true)
182 found = s.t.HasService("s-1")
183 c.Assert(found, Equals, false)
184 }
185
186 func (s TopologySuite) TestServiceKey(c *C) {
187 // Check that the key retrieval for a service name works correctly.
188 key, err := s.t.ServiceKey("wordpress")
189 c.Assert(err, ErrorMatches, `service with name "wordpress" not found`)
190 err = s.t.AddService("s-0", "wordpress")
191 c.Assert(err, IsNil)
192 key, err = s.t.ServiceKey("wordpress")
193 c.Assert(err, IsNil)
194 c.Assert(key, Equals, "s-0")
195 }
196
197 func (s TopologySuite) TestServiceKeys(c *C) {
198 // Check that the retrieval of all services keys works correctly.
199 keys := s.t.ServiceKeys()
200 c.Assert(keys, DeepEquals, []string{})
201 err := s.t.AddService("s-0", "wordpress")
202 c.Assert(err, IsNil)
203 err = s.t.AddService("s-1", "mysql")
204 c.Assert(err, IsNil)
205 keys = s.t.ServiceKeys()
206 c.Assert(keys, DeepEquals, []string{"s-0", "s-1"})
207 }
208
209 func (s TopologySuite) TestServiceName(c *C) {
210 // Check that the name retrieval for a service name works correctly.
211 name, err := s.t.ServiceName("s-0")
212 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
213 err = s.t.AddService("s-0", "wordpress")
214 c.Assert(err, IsNil)
215 name, err = s.t.ServiceName("s-0")
216 c.Assert(err, IsNil)
217 c.Assert(name, Equals, "wordpress")
218 }
219
220 func (s TopologySuite) TestRemoveService(c *C) {
221 // Check that the removing of a service works correctly.
222 err := s.t.AddService("s-0", "wordpress")
223 c.Assert(err, IsNil)
224 err = s.t.AddService("s-1", "mysql")
225 c.Assert(err, IsNil)
226 err = s.t.RemoveService("s-0")
227 c.Assert(err, IsNil)
228 c.Assert(s.t.HasService("s-0"), Equals, false)
229 c.Assert(s.t.HasService("s-1"), Equals, true)
230 }
231
232 func (s TopologySuite) TestRemoveNonExistentService(c *C) {
233 // Check that the removing of a non-existent service fails.
234 err := s.t.RemoveService("s-99")
235 c.Assert(err, ErrorMatches, `service with key "s-99" not found`)
236 }
237
238 func (s TopologySuite) TestAddUnit(c *C) {
239 // Check that the adding of a unit works correctly.
240 err := s.t.AddService("s-0", "wordpress")
241 c.Assert(err, IsNil)
242 err = s.t.AddService("s-1", "mysql")
243 c.Assert(err, IsNil)
244 seq, err := s.t.AddUnit("s-0", "u-05")
245 c.Assert(err, IsNil)
246 c.Assert(seq, Equals, 0)
247 seq, err = s.t.AddUnit("s-0", "u-12")
248 c.Assert(err, IsNil)
249 c.Assert(seq, Equals, 1)
250 seq, err = s.t.AddUnit("s-1", "u-07")
251 c.Assert(err, IsNil)
252 c.Assert(seq, Equals, 0)
253 keys, err := s.t.UnitKeys("s-0")
254 c.Assert(err, IsNil)
255 c.Assert(keys, DeepEquals, []string{"u-05", "u-12"})
256 keys, err = s.t.UnitKeys("s-1")
257 c.Assert(err, IsNil)
258 c.Assert(keys, DeepEquals, []string{"u-07"})
259 }
260
261 func (s TopologySuite) TestGlobalUniqueUnitNames(c *C) {
262 // Check that even if the underlying service is destroyed
263 // and a new one with the same name is created we'll never
264 // get a duplicate unit name.
265 err := s.t.AddService("s-0", "wordpress")
266 c.Assert(err, IsNil)
267 seq, err := s.t.AddUnit("s-0", "u-0")
268 c.Assert(err, IsNil)
269 c.Assert(seq, Equals, 0)
270 seq, err = s.t.AddUnit("s-0", "u-1")
271 c.Assert(err, IsNil)
272 c.Assert(seq, Equals, 1)
273 err = s.t.RemoveService("s-0")
274 c.Assert(err, IsNil)
275 err = s.t.AddService("s-0", "wordpress")
276 c.Assert(err, IsNil)
277 seq, err = s.t.AddUnit("s-0", "u-1")
278 c.Assert(err, IsNil)
279 c.Assert(seq, Equals, 2)
280 name, err := s.t.UnitName("s-0", "u-1")
281 c.Assert(err, IsNil)
282 c.Assert(name, Equals, "wordpress/2")
283 }
284
285 func (s TopologySuite) TestAddDuplicatedUnit(c *C) {
286 // Check that it's not possible to add a unit twice.
287 err := s.t.AddService("s-0", "wordpress")
288 c.Assert(err, IsNil)
289 _, err = s.t.AddUnit("s-0", "u-0")
290 c.Assert(err, IsNil)
291 _, err = s.t.AddUnit("s-0", "u-0")
292 c.Assert(err, ErrorMatches, `unit "u-0" already in use in service "s-0"` )
293 }
294
295 func (s TopologySuite) TestAddUnitToNonExistingService(c *C) {
296 // Check that the adding of a unit to a non-existing services
297 // fails correctly.
298 _, err := s.t.AddUnit("s-0", "u-0")
299 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
300 }
301
302 func (s TopologySuite) TestAddUnitToDifferentService(c *C) {
303 // Check that the adding of the same unit to two different
304 // services fails correctly.
305 err := s.t.AddService("s-0", "wordpress")
306 c.Assert(err, IsNil)
307 err = s.t.AddService("s-1", "mysql")
308 c.Assert(err, IsNil)
309 _, err = s.t.AddUnit("s-0", "u-0")
310 c.Assert(err, IsNil)
311 _, err = s.t.AddUnit("s-1", "u-0")
312 c.Assert(err, ErrorMatches, `unit "u-0" already in use in service "s-0"` )
313 }
314
315 func (s TopologySuite) TestUnitKeys(c *C) {
316 // Check if registered units from a service are returned correctly.
317 err := s.t.AddService("s-0", "wordpress")
318 c.Assert(err, IsNil)
319 err = s.t.AddService("s-1", "mysql")
320 c.Assert(err, IsNil)
321 units, err := s.t.UnitKeys("s-0")
322 c.Assert(err, IsNil)
323 c.Assert(units, DeepEquals, []string{})
324 _, err = s.t.AddUnit("s-0", "u-0")
325 c.Assert(err, IsNil)
326 _, err = s.t.AddUnit("s-0", "u-1")
327 c.Assert(err, IsNil)
328 _, err = s.t.AddUnit("s-1", "u-2")
329 c.Assert(err, IsNil)
330 units, err = s.t.UnitKeys("s-0")
331 c.Assert(err, IsNil)
332 c.Assert(units, DeepEquals, []string{"u-0", "u-1"})
333 units, err = s.t.UnitKeys("s-1")
334 c.Assert(err, IsNil)
335 c.Assert(units, DeepEquals, []string{"u-2"})
336 }
337
338 func (s TopologySuite) TestUnitKeysWithNonExistingService(c *C) {
339 // Check if the retrieving of unit keys from a non-existing
340 // service fails correctly.
341 _, err := s.t.UnitKeys("s-0")
342 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
343 }
344
345 func (s TopologySuite) TestHasUnit(c *C) {
346 // Check that the test for a unit in a service works correctly.
347 err := s.t.AddService("s-0", "wordpress")
348 c.Assert(err, IsNil)
349 found := s.t.HasUnit("s-0", "u-0")
350 c.Assert(found, Equals, false)
351 _, err = s.t.AddUnit("s-0", "u-0")
352 c.Assert(err, IsNil)
353 found = s.t.HasUnit("s-0", "u-0")
354 c.Assert(found, Equals, true)
355 found = s.t.HasUnit("s-0", "u-1")
356 c.Assert(found, Equals, false)
357 }
358
359 func (s TopologySuite) TestUnitName(c *C) {
360 // Check that the human readable names are returned correctly.
361 err := s.t.AddService("s-0", "wordpress")
362 c.Assert(err, IsNil)
363 err = s.t.AddService("s-1", "mysql")
364 c.Assert(err, IsNil)
365 _, err = s.t.AddUnit("s-0", "u-0")
366 c.Assert(err, IsNil)
367 _, err = s.t.AddUnit("s-0", "u-1")
368 c.Assert(err, IsNil)
369 _, err = s.t.AddUnit("s-1", "u-2")
370 c.Assert(err, IsNil)
371 name, err := s.t.UnitName("s-0", "u-0")
372 c.Assert(err, IsNil)
373 c.Assert(name, Equals, "wordpress/0")
374 name, err = s.t.UnitName("s-0", "u-1")
375 c.Assert(err, IsNil)
376 c.Assert(name, Equals, "wordpress/1")
377 name, err = s.t.UnitName("s-1", "u-2")
378 c.Assert(err, IsNil)
379 c.Assert(name, Equals, "mysql/0")
380 }
381
382 func (s TopologySuite) TestUnitNameWithNonExistingServiceOrUnit(c *C) {
383 // Check if the retrieval of unit names fails if the service
384 // or the unit doesn't exist.
385 _, err := s.t.UnitName("s-0", "u-1")
386 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
387 err = s.t.AddService("s-0", "wordpress")
388 c.Assert(err, IsNil)
389 _, err = s.t.UnitName("s-0", "u-1")
390 c.Assert(err, ErrorMatches, `unit with key "u-1" not found`)
391 _, err = s.t.AddUnit("s-0", "u-0")
392 c.Assert(err, IsNil)
393 _, err = s.t.UnitName("s-0", "u-1")
394 c.Assert(err, ErrorMatches, `unit with key "u-1" not found`)
395 }
396
397 func (s TopologySuite) TestRemoveUnit(c *C) {
398 // Check that the removing of a unit works correctly.
399 err := s.t.AddService("s-0", "wordpress")
400 c.Assert(err, IsNil)
401 _, err = s.t.AddUnit("s-0", "u-0")
402 c.Assert(err, IsNil)
403 _, err = s.t.AddUnit("s-0", "u-1")
404 c.Assert(err, IsNil)
405 err = s.t.RemoveUnit("s-0", "u-0")
406 c.Assert(err, IsNil)
407 found := s.t.HasUnit("s-0", "u-0")
408 c.Assert(found, Equals, false)
409 found = s.t.HasUnit("s-0", "u-1")
410 c.Assert(found, Equals, true)
411 }
412
413 func (s TopologySuite) TestRemoveNonExistingUnit(c *C) {
414 // Check that the removing of non-existing units fails.
415 err := s.t.RemoveUnit("s-0", "u-0")
416 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
417 err = s.t.AddService("s-0", "wordpress")
418 c.Assert(err, IsNil)
419 err = s.t.RemoveUnit("s-0", "u-0")
420 c.Assert(err, ErrorMatches, `unit with key "u-0" not found`)
421 }
422
423 func (s TopologySuite) TestUnitKeyFromSequence(c *C) {
424 // Check that the retrieving of a unit key by service key
425 // and sequence number works correctly.
426 err := s.t.AddService("s-0", "wordpress")
427 c.Assert(err, IsNil)
428 _, err = s.t.AddUnit("s-0", "u-0")
429 c.Assert(err, IsNil)
430 _, err = s.t.AddUnit("s-0", "u-1")
431 c.Assert(err, IsNil)
432 key, err := s.t.UnitKeyFromSequence("s-0", 0)
433 c.Assert(err, IsNil)
434 c.Assert(key, Equals, "u-0")
435 key, err = s.t.UnitKeyFromSequence("s-0", 1)
436 c.Assert(err, IsNil)
437 c.Assert(key, Equals, "u-1")
438 key, err = s.t.UnitKeyFromSequence("s-0", 2)
439 c.Assert(err, ErrorMatches, `unit with sequence number 2 not found`)
440 }
441
442 func (s TopologySuite) TestUnitKeyFromNonExistingService(c *C) {
443 _, err := s.t.UnitKeyFromSequence("s-0", 0)
444 c.Assert(err, ErrorMatches, `service with key "s-0" not found`)
445 }
446
447 type ConfigNodeSuite struct {
448 zkServer *zookeeper.Server
449 zkTestRoot string
450 zkTestPort int
451 zkAddr string
452 zkConn *zookeeper.Conn
453 path string
454 }
455
456 var _ = Suite(&ConfigNodeSuite{})
457
458 func (s *ConfigNodeSuite) SetUpSuite(c *C) {
459 s.path = "/config"
460 }
461
462 func (s *ConfigNodeSuite) SetUpTest(c *C) {
463 // Connect the server.
464 st, err := Open(&Info{
465 Addrs: []string{TestingZkAddr},
466 })
467 c.Assert(err, IsNil)
468 s.zkConn = ZkConn(st)
469 }
470
471 func (s *ConfigNodeSuite) TearDownTest(c *C) {
472 // Delete possible nodes, ignore errors.
473 zkRemoveTree(s.zkConn, s.path)
474 s.zkConn.Close()
475 }
476
477 func (s ConfigNodeSuite) TestCreateEmptyConfigNode(c *C) {
478 // Check that creating an empty node works correctly.
479 node, err := createConfigNode(s.zkConn, s.path, nil)
480 c.Assert(err, IsNil)
481 c.Assert(node.Keys(), DeepEquals, []string{})
482 }
483
484 func (s ConfigNodeSuite) TestReadWithoutWrite(c *C) {
485 // Check reading without writing.
486 node, err := readConfigNode(s.zkConn, s.path)
487 c.Assert(err, IsNil)
488 c.Assert(node, Not(IsNil))
489 }
490
491 func (s ConfigNodeSuite) TestSetWithoutWrite(c *C) {
492 // Check that config values can be set.
493 _, err := s.zkConn.Create(s.path, "", 0, zkPermAll)
494 c.Assert(err, IsNil)
495 node, err := readConfigNode(s.zkConn, s.path)
496 c.Assert(err, IsNil)
497 options := map[string]interface{}{"alpha": "beta", "one": 1}
498 node.Update(options)
499 c.Assert(node.Map(), DeepEquals, options)
500 // Node data has to be empty.
501 yaml, _, err := s.zkConn.Get("/config")
502 c.Assert(err, IsNil)
503 c.Assert(yaml, Equals, "")
504 }
505
506 func (s ConfigNodeSuite) TestSetWithWrite(c *C) {
507 // Check that write updates the local and the ZooKeeper state.
508 node, err := readConfigNode(s.zkConn, s.path)
509 c.Assert(err, IsNil)
510 options := map[string]interface{}{"alpha": "beta", "one": 1}
511 node.Update(options)
512 changes, err := node.Write()
513 c.Assert(err, IsNil)
514 c.Assert(changes, DeepEquals, []ItemChange{
515 {ItemAdded, "alpha", nil, "beta"},
516 {ItemAdded, "one", nil, 1},
517 })
518 // Check local state.
519 c.Assert(node.Map(), DeepEquals, options)
520 // Check ZooKeeper state.
521 yaml, _, err := s.zkConn.Get(s.path)
522 c.Assert(err, IsNil)
523 zkData := make(map[string]interface{})
524 err = goyaml.Unmarshal([]byte(yaml), zkData)
525 c.Assert(zkData, DeepEquals, options)
526 }
527
528 func (s ConfigNodeSuite) TestConflictOnSet(c *C) {
529 // Check version conflict errors.
530 nodeOne, err := readConfigNode(s.zkConn, s.path)
531 c.Assert(err, IsNil)
532 nodeTwo, err := readConfigNode(s.zkConn, s.path)
533 c.Assert(err, IsNil)
534
535 optionsOld := map[string]interface{}{"alpha": "beta", "one": 1}
536 nodeOne.Update(optionsOld)
537 nodeOne.Write()
538
539 nodeTwo.Update(optionsOld)
540 changes, err := nodeTwo.Write()
541 c.Assert(err, IsNil)
542 c.Assert(changes, DeepEquals, []ItemChange{
543 {ItemAdded, "alpha", nil, "beta"},
544 {ItemAdded, "one", nil, 1},
545 })
546
547 // First test node one.
548 c.Assert(nodeOne.Map(), DeepEquals, optionsOld)
549
550 // Write on node one.
551 optionsNew := map[string]interface{}{"alpha": "gamma", "one": "two"}
552 nodeOne.Update(optionsNew)
553 changes, err = nodeOne.Write()
554 c.Assert(err, IsNil)
555 c.Assert(changes, DeepEquals, []ItemChange{
556 {ItemModified, "alpha", "beta", "gamma"},
557 {ItemModified, "one", 1, "two"},
558 })
559
560 // Verify that node one reports as expected.
561 c.Assert(nodeOne.Map(), DeepEquals, optionsNew)
562
563 // Verify that node two has still the old data.
564 c.Assert(nodeTwo.Map(), DeepEquals, optionsOld)
565
566 // Now issue a Set/Write from node two. This will
567 // merge the data deleting 'one' and updating
568 // other values.
569 optionsMerge := map[string]interface{}{"alpha": "cappa", "new": "next"}
570 nodeTwo.Update(optionsMerge)
571 nodeTwo.Delete("one")
572
573 expected := map[string]interface{}{"alpha": "cappa", "new": "next"}
574 changes, err = nodeTwo.Write()
575 c.Assert(err, IsNil)
576 c.Assert(changes, DeepEquals, []ItemChange{
577 {ItemModified, "alpha", "beta", "cappa"},
578 {ItemAdded, "new", nil, "next"},
579 {ItemDeleted, "one", 1, nil},
580 })
581 c.Assert(expected, DeepEquals, nodeTwo.Map())
582
583 // But node one still reflects the former data.
584 c.Assert(nodeOne.Map(), DeepEquals, optionsNew)
585 }
586
587 func (s ConfigNodeSuite) TestSetItem(c *C) {
588 // Check that Set works as expected.
589 node, err := readConfigNode(s.zkConn, s.path)
590 c.Assert(err, IsNil)
591 options := map[string]interface{}{"alpha": "beta", "one": 1}
592 node.Set("alpha", "beta")
593 node.Set("one", 1)
594 changes, err := node.Write()
595 c.Assert(err, IsNil)
596 c.Assert(changes, DeepEquals, []ItemChange{
597 {ItemAdded, "alpha", nil, "beta"},
598 {ItemAdded, "one", nil, 1},
599 })
600 // Check local state.
601 c.Assert(node.Map(), DeepEquals, options)
602 // Check ZooKeeper state.
603 yaml, _, err := s.zkConn.Get(s.path)
604 c.Assert(err, IsNil)
605 zkData := make(map[string]interface{})
606 err = goyaml.Unmarshal([]byte(yaml), zkData)
607 c.Assert(zkData, DeepEquals, options)
608 }
609
610 func (s ConfigNodeSuite) TestMultipleReads(c *C) {
611 // Check that reads without writes always resets the data.
612 nodeOne, err := readConfigNode(s.zkConn, s.path)
613 c.Assert(err, IsNil)
614 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"})
615 value, ok := nodeOne.Get("alpha")
616 c.Assert(ok, Equals, true)
617 c.Assert(value, Equals, "beta")
618 value, ok = nodeOne.Get("foo")
619 c.Assert(ok, Equals, true)
620 c.Assert(value, Equals, "bar")
621 value, ok = nodeOne.Get("baz")
622 c.Assert(ok, Equals, false)
623
624 // A read resets the data to the empty state.
625 err = nodeOne.Read()
626 c.Assert(err, IsNil)
627 c.Assert(nodeOne.Map(), DeepEquals, map[string]interface{}{})
628 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"})
629 changes, err := nodeOne.Write()
630 c.Assert(err, IsNil)
631 c.Assert(changes, DeepEquals, []ItemChange{
632 {ItemAdded, "alpha", nil, "beta"},
633 {ItemAdded, "foo", nil, "bar"},
634 })
635
636 // A write retains the newly set values.
637 value, ok = nodeOne.Get("alpha")
638 c.Assert(ok, Equals, true)
639 c.Assert(value, Equals, "beta")
640 value, ok = nodeOne.Get("foo")
641 c.Assert(ok, Equals, true)
642 c.Assert(value, Equals, "bar")
643
644 // Now get another state instance and change ZooKeeper state.
645 nodeTwo, err := readConfigNode(s.zkConn, s.path)
646 c.Assert(err, IsNil)
647 nodeTwo.Update(map[string]interface{}{"foo": "different"})
648 changes, err = nodeTwo.Write()
649 c.Assert(err, IsNil)
650 c.Assert(changes, DeepEquals, []ItemChange{
651 {ItemModified, "foo", "bar", "different"},
652 })
653
654 // This should pull in the new state into node one.
655 err = nodeOne.Read()
656 c.Assert(err, IsNil)
657 value, ok = nodeOne.Get("alpha")
658 c.Assert(ok, Equals, true)
659 c.Assert(value, Equals, "beta")
660 value, ok = nodeOne.Get("foo")
661 c.Assert(ok, Equals, true)
662 c.Assert(value, Equals, "different")
663 }
664
665 func (s ConfigNodeSuite) TestDeleteEmptiesState(c *C) {
666 // Check that delete creates an empty state.
667 node, err := readConfigNode(s.zkConn, s.path)
668 c.Assert(err, IsNil)
669 node.Set("a", "foo")
670 changes, err := node.Write()
671 c.Assert(err, IsNil)
672 c.Assert(changes, DeepEquals, []ItemChange{
673 {ItemAdded, "a", nil, "foo"},
674 })
675 node.Delete("a")
676 changes, err = node.Write()
677 c.Assert(err, IsNil)
678 c.Assert(changes, DeepEquals, []ItemChange{
679 {ItemDeleted, "a", "foo", nil},
680 })
681 c.Assert(node.Map(), DeepEquals, map[string]interface{}{})
682 }
683
684 func (s ConfigNodeSuite) TestReadResync(c *C) {
685 // Check that read pulls the data into the node.
686 nodeOne, err := readConfigNode(s.zkConn, s.path)
687 c.Assert(err, IsNil)
688 nodeOne.Set("a", "foo")
689 changes, err := nodeOne.Write()
690 c.Assert(err, IsNil)
691 c.Assert(changes, DeepEquals, []ItemChange{
692 {ItemAdded, "a", nil, "foo"},
693 })
694 nodeTwo, err := readConfigNode(s.zkConn, s.path)
695 c.Assert(err, IsNil)
696 nodeTwo.Delete("a")
697 changes, err = nodeTwo.Write()
698 c.Assert(err, IsNil)
699 c.Assert(changes, DeepEquals, []ItemChange{
700 {ItemDeleted, "a", "foo", nil},
701 })
702 nodeTwo.Set("a", "bar")
703 changes, err = nodeTwo.Write()
704 c.Assert(err, IsNil)
705 c.Assert(changes, DeepEquals, []ItemChange{
706 {ItemAdded, "a", nil, "bar"},
707 })
708 // Read of node one should pick up the new value.
709 err = nodeOne.Read()
710 c.Assert(err, IsNil)
711 value, ok := nodeOne.Get("a")
712 c.Assert(ok, Equals, true)
713 c.Assert(value, Equals, "bar")
714 }
715
716 func (s ConfigNodeSuite) TestMultipleWrites(c *C) {
717 // Check that multiple writes only do the right changes.
718 node, err := readConfigNode(s.zkConn, s.path)
719 c.Assert(err, IsNil)
720 node.Update(map[string]interface{}{"foo": "bar", "this": "that"})
721 changes, err := node.Write()
722 c.Assert(err, IsNil)
723 c.Assert(changes, DeepEquals, []ItemChange{
724 {ItemAdded, "foo", nil, "bar"},
725 {ItemAdded, "this", nil, "that"},
726 })
727 node.Delete("this")
728 node.Set("another", "value")
729 changes, err = node.Write()
730 c.Assert(err, IsNil)
731 c.Assert(changes, DeepEquals, []ItemChange{
732 {ItemAdded, "another", nil, "value"},
733 {ItemDeleted, "this", "that", nil},
734 })
735
736 expected := map[string]interface{}{"foo": "bar", "another": "value"}
737 c.Assert(expected, DeepEquals, node.Map())
738
739 changes, err = node.Write()
740 c.Assert(err, IsNil)
741 c.Assert(changes, DeepEquals, []ItemChange{})
742
743 err = node.Read()
744 c.Assert(err, IsNil)
745 c.Assert(expected, DeepEquals, node.Map())
746
747 changes, err = node.Write()
748 c.Assert(err, IsNil)
749 c.Assert(changes, DeepEquals, []ItemChange{})
750 }
751
752 func (s ConfigNodeSuite) TestWriteTwice(c *C) {
753 // Check the correct writing into a node by two config nodes.
754 nodeOne, err := readConfigNode(s.zkConn, s.path)
755 c.Assert(err, IsNil)
756 nodeOne.Set("a", "foo")
757 changes, err := nodeOne.Write()
758 c.Assert(err, IsNil)
759 c.Assert(changes, DeepEquals, []ItemChange{
760 {ItemAdded, "a", nil, "foo"},
761 })
762
763 nodeTwo, err := readConfigNode(s.zkConn, s.path)
764 c.Assert(err, IsNil)
765 nodeTwo.Set("a", "bar")
766 changes, err = nodeTwo.Write()
767 c.Assert(err, IsNil)
768 c.Assert(changes, DeepEquals, []ItemChange{
769 {ItemModified, "a", "foo", "bar"},
770 })
771
772 // Shouldn't write again. Changes were already
773 // flushed and acted upon by other parties.
774 changes, err = nodeOne.Write()
775 c.Assert(err, IsNil)
776 c.Assert(changes, DeepEquals, []ItemChange{})
777
778 err = nodeOne.Read()
779 c.Assert(err, IsNil)
780 c.Assert(nodeOne, DeepEquals, nodeTwo)
781 }
782
783 type QuoteSuite struct{}
784
785 var _ = Suite(&QuoteSuite{})
786
787 func (s QuoteSuite) TestUnmodified(c *C) {
788 // Check that a string containig only valid
789 // chars stays unmodified.
790 in := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-"
791 out := Quote(in)
792 c.Assert(out, Equals, in)
793 }
794
795 func (s QuoteSuite) TestQuote(c *C) {
796 // Check that invalid chars are translated correctly.
797 in := "hello_there/how'are~you-today.sir"
798 out := Quote(in)
799 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir")
800 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b