LEFT | RIGHT |
1 // launchpad.net/juju/go/state | 1 // launchpad.net/juju/go/state |
2 // | 2 // |
3 // Copyright (c) 2011-2012 Canonical Ltd. | 3 // Copyright (c) 2011-2012 Canonical Ltd. |
4 package state | 4 package state |
5 | 5 |
6 import ( | 6 import ( |
7 . "launchpad.net/gocheck" | 7 . "launchpad.net/gocheck" |
8 "launchpad.net/goyaml" | 8 "launchpad.net/goyaml" |
9 "launchpad.net/gozk/zookeeper" | 9 "launchpad.net/gozk/zookeeper" |
10 ) | 10 ) |
(...skipping 27 matching lines...) Expand all Loading... |
38 s.zkConn.Close() | 38 s.zkConn.Close() |
39 } | 39 } |
40 | 40 |
41 func (s TopologySuite) TestAddMachine(c *C) { | 41 func (s TopologySuite) TestAddMachine(c *C) { |
42 // Check that adding machines works correctly. | 42 // Check that adding machines works correctly. |
43 err := s.t.AddMachine("m-0") | 43 err := s.t.AddMachine("m-0") |
44 c.Assert(err, IsNil) | 44 c.Assert(err, IsNil) |
45 err = s.t.AddMachine("m-1") | 45 err = s.t.AddMachine("m-1") |
46 c.Assert(err, IsNil) | 46 c.Assert(err, IsNil) |
47 keys := s.t.MachineKeys() | 47 keys := s.t.MachineKeys() |
48 » c.Assert(keys, Equals, []string{"m-0", "m-1"}) | 48 » c.Assert(keys, DeepEquals, []string{"m-0", "m-1"}) |
49 } | 49 } |
50 | 50 |
51 func (s TopologySuite) TestAddDuplicatedMachine(c *C) { | 51 func (s TopologySuite) TestAddDuplicatedMachine(c *C) { |
52 // Check that adding a duplicated machine by key fails. | 52 // Check that adding a duplicated machine by key fails. |
53 err := s.t.AddMachine("m-0") | 53 err := s.t.AddMachine("m-0") |
54 c.Assert(err, IsNil) | 54 c.Assert(err, IsNil) |
55 err = s.t.AddMachine("m-0") | 55 err = s.t.AddMachine("m-0") |
56 c.Assert(err, ErrorMatches, `attempted to add duplicated machine "m-0"`) | 56 c.Assert(err, ErrorMatches, `attempted to add duplicated machine "m-0"`) |
57 } | 57 } |
58 | 58 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 _, err = s.t.AddUnit("s-0", "u-1") | 95 _, err = s.t.AddUnit("s-0", "u-1") |
96 c.Assert(err, IsNil) | 96 c.Assert(err, IsNil) |
97 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0") | 97 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0") |
98 c.Assert(err, IsNil) | 98 c.Assert(err, IsNil) |
99 err = s.t.RemoveMachine("m-0") | 99 err = s.t.RemoveMachine("m-0") |
100 c.Assert(err, ErrorMatches, `can't remove machine "m-0" while units ared
assigned`) | 100 c.Assert(err, ErrorMatches, `can't remove machine "m-0" while units ared
assigned`) |
101 } | 101 } |
102 | 102 |
103 func (s TopologySuite) TestMachineHasUnits(c *C) { | 103 func (s TopologySuite) TestMachineHasUnits(c *C) { |
104 // Check various ways a machine might or might not be assigned | 104 // Check various ways a machine might or might not be assigned |
105 » // to a unit.» | 105 » // to a unit. |
106 err := s.t.AddMachine("m-0") | 106 err := s.t.AddMachine("m-0") |
107 c.Assert(err, IsNil) | 107 c.Assert(err, IsNil) |
108 err = s.t.AddMachine("m-1") | 108 err = s.t.AddMachine("m-1") |
109 c.Assert(err, IsNil) | 109 c.Assert(err, IsNil) |
110 err = s.t.AddService("s-0", "wordpress") | 110 err = s.t.AddService("s-0", "wordpress") |
111 c.Assert(err, IsNil) | 111 c.Assert(err, IsNil) |
112 _, err = s.t.AddUnit("s-0", "u-0") | 112 _, err = s.t.AddUnit("s-0", "u-0") |
113 c.Assert(err, IsNil) | 113 c.Assert(err, IsNil) |
114 _, err = s.t.AddUnit("s-0", "u-1") | 114 _, err = s.t.AddUnit("s-0", "u-1") |
115 c.Assert(err, IsNil) | 115 c.Assert(err, IsNil) |
(...skipping 17 matching lines...) Expand all Loading... |
133 c.Assert(err, IsNil) | 133 c.Assert(err, IsNil) |
134 found = s.t.HasMachine("m-0") | 134 found = s.t.HasMachine("m-0") |
135 c.Assert(found, Equals, true) | 135 c.Assert(found, Equals, true) |
136 found = s.t.HasMachine("m-1") | 136 found = s.t.HasMachine("m-1") |
137 c.Assert(found, Equals, false) | 137 c.Assert(found, Equals, false) |
138 } | 138 } |
139 | 139 |
140 func (s TopologySuite) TestMachineKeys(c *C) { | 140 func (s TopologySuite) TestMachineKeys(c *C) { |
141 // Check that the retrieval of all services keys works correctly. | 141 // Check that the retrieval of all services keys works correctly. |
142 keys := s.t.MachineKeys() | 142 keys := s.t.MachineKeys() |
143 » c.Assert(keys, Equals, []string{}) | 143 » c.Assert(keys, DeepEquals, []string{}) |
144 err := s.t.AddMachine("m-0") | 144 err := s.t.AddMachine("m-0") |
145 c.Assert(err, IsNil) | 145 c.Assert(err, IsNil) |
146 err = s.t.AddMachine("m-1") | 146 err = s.t.AddMachine("m-1") |
147 c.Assert(err, IsNil) | 147 c.Assert(err, IsNil) |
148 keys = s.t.MachineKeys() | 148 keys = s.t.MachineKeys() |
149 » c.Assert(keys, Equals, []string{"m-0", "m-1"}) | 149 » c.Assert(keys, DeepEquals, []string{"m-0", "m-1"}) |
150 } | 150 } |
151 | 151 |
152 func (s TopologySuite) TestAddService(c *C) { | 152 func (s TopologySuite) TestAddService(c *C) { |
153 // Check that adding services works correctly. | 153 // Check that adding services works correctly. |
154 c.Assert(s.t.HasService("s-0"), Equals, false) | 154 c.Assert(s.t.HasService("s-0"), Equals, false) |
155 err := s.t.AddService("s-0", "wordpress") | 155 err := s.t.AddService("s-0", "wordpress") |
156 c.Assert(err, IsNil) | 156 c.Assert(err, IsNil) |
157 err = s.t.AddService("s-1", "mysql") | 157 err = s.t.AddService("s-1", "mysql") |
158 c.Assert(err, IsNil) | 158 c.Assert(err, IsNil) |
159 c.Assert(s.t.HasService("s-0"), Equals, true) | 159 c.Assert(s.t.HasService("s-0"), Equals, true) |
(...skipping 29 matching lines...) Expand all Loading... |
189 err = s.t.AddService("s-0", "wordpress") | 189 err = s.t.AddService("s-0", "wordpress") |
190 c.Assert(err, IsNil) | 190 c.Assert(err, IsNil) |
191 key, err = s.t.ServiceKey("wordpress") | 191 key, err = s.t.ServiceKey("wordpress") |
192 c.Assert(err, IsNil) | 192 c.Assert(err, IsNil) |
193 c.Assert(key, Equals, "s-0") | 193 c.Assert(key, Equals, "s-0") |
194 } | 194 } |
195 | 195 |
196 func (s TopologySuite) TestServiceKeys(c *C) { | 196 func (s TopologySuite) TestServiceKeys(c *C) { |
197 // Check that the retrieval of all services keys works correctly. | 197 // Check that the retrieval of all services keys works correctly. |
198 keys := s.t.ServiceKeys() | 198 keys := s.t.ServiceKeys() |
199 » c.Assert(keys, Equals, []string{}) | 199 » c.Assert(keys, DeepEquals, []string{}) |
200 err := s.t.AddService("s-0", "wordpress") | 200 err := s.t.AddService("s-0", "wordpress") |
201 c.Assert(err, IsNil) | 201 c.Assert(err, IsNil) |
202 err = s.t.AddService("s-1", "mysql") | 202 err = s.t.AddService("s-1", "mysql") |
203 c.Assert(err, IsNil) | 203 c.Assert(err, IsNil) |
204 keys = s.t.ServiceKeys() | 204 keys = s.t.ServiceKeys() |
205 » c.Assert(keys, Equals, []string{"s-0", "s-1"}) | 205 » c.Assert(keys, DeepEquals, []string{"s-0", "s-1"}) |
206 } | 206 } |
207 | 207 |
208 func (s TopologySuite) TestServiceName(c *C) { | 208 func (s TopologySuite) TestServiceName(c *C) { |
209 // Check that the name retrieval for a service name works correctly. | 209 // Check that the name retrieval for a service name works correctly. |
210 name, err := s.t.ServiceName("s-0") | 210 name, err := s.t.ServiceName("s-0") |
211 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) | 211 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) |
212 err = s.t.AddService("s-0", "wordpress") | 212 err = s.t.AddService("s-0", "wordpress") |
213 c.Assert(err, IsNil) | 213 c.Assert(err, IsNil) |
214 name, err = s.t.ServiceName("s-0") | 214 name, err = s.t.ServiceName("s-0") |
215 c.Assert(err, IsNil) | 215 c.Assert(err, IsNil) |
(...skipping 28 matching lines...) Expand all Loading... |
244 c.Assert(err, IsNil) | 244 c.Assert(err, IsNil) |
245 c.Assert(seq, Equals, 0) | 245 c.Assert(seq, Equals, 0) |
246 seq, err = s.t.AddUnit("s-0", "u-12") | 246 seq, err = s.t.AddUnit("s-0", "u-12") |
247 c.Assert(err, IsNil) | 247 c.Assert(err, IsNil) |
248 c.Assert(seq, Equals, 1) | 248 c.Assert(seq, Equals, 1) |
249 seq, err = s.t.AddUnit("s-1", "u-07") | 249 seq, err = s.t.AddUnit("s-1", "u-07") |
250 c.Assert(err, IsNil) | 250 c.Assert(err, IsNil) |
251 c.Assert(seq, Equals, 0) | 251 c.Assert(seq, Equals, 0) |
252 keys, err := s.t.UnitKeys("s-0") | 252 keys, err := s.t.UnitKeys("s-0") |
253 c.Assert(err, IsNil) | 253 c.Assert(err, IsNil) |
254 » c.Assert(keys, Equals, []string{"u-05", "u-12"}) | 254 » c.Assert(keys, DeepEquals, []string{"u-05", "u-12"}) |
255 keys, err = s.t.UnitKeys("s-1") | 255 keys, err = s.t.UnitKeys("s-1") |
256 c.Assert(err, IsNil) | 256 c.Assert(err, IsNil) |
257 » c.Assert(keys, Equals, []string{"u-07"}) | 257 » c.Assert(keys, DeepEquals, []string{"u-07"}) |
258 } | 258 } |
259 | 259 |
260 func (s TopologySuite) TestGlobalUniqueUnitNames(c *C) { | 260 func (s TopologySuite) TestGlobalUniqueUnitNames(c *C) { |
261 // Check that even if the underlying service is destroyed | 261 // Check that even if the underlying service is destroyed |
262 // and a new one with the same name is created we'll never | 262 // and a new one with the same name is created we'll never |
263 // get a duplicate unit name. | 263 // get a duplicate unit name. |
264 err := s.t.AddService("s-0", "wordpress") | 264 err := s.t.AddService("s-0", "wordpress") |
265 c.Assert(err, IsNil) | 265 c.Assert(err, IsNil) |
266 seq, err := s.t.AddUnit("s-0", "u-0") | 266 seq, err := s.t.AddUnit("s-0", "u-0") |
267 c.Assert(err, IsNil) | 267 c.Assert(err, IsNil) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 } | 312 } |
313 | 313 |
314 func (s TopologySuite) TestUnitKeys(c *C) { | 314 func (s TopologySuite) TestUnitKeys(c *C) { |
315 // Check if registered units from a service are returned correctly. | 315 // Check if registered units from a service are returned correctly. |
316 err := s.t.AddService("s-0", "wordpress") | 316 err := s.t.AddService("s-0", "wordpress") |
317 c.Assert(err, IsNil) | 317 c.Assert(err, IsNil) |
318 err = s.t.AddService("s-1", "mysql") | 318 err = s.t.AddService("s-1", "mysql") |
319 c.Assert(err, IsNil) | 319 c.Assert(err, IsNil) |
320 units, err := s.t.UnitKeys("s-0") | 320 units, err := s.t.UnitKeys("s-0") |
321 c.Assert(err, IsNil) | 321 c.Assert(err, IsNil) |
322 » c.Assert(units, Equals, []string{}) | 322 » c.Assert(units, DeepEquals, []string{}) |
323 _, err = s.t.AddUnit("s-0", "u-0") | 323 _, err = s.t.AddUnit("s-0", "u-0") |
324 c.Assert(err, IsNil) | 324 c.Assert(err, IsNil) |
325 _, err = s.t.AddUnit("s-0", "u-1") | 325 _, err = s.t.AddUnit("s-0", "u-1") |
326 c.Assert(err, IsNil) | 326 c.Assert(err, IsNil) |
327 _, err = s.t.AddUnit("s-1", "u-2") | 327 _, err = s.t.AddUnit("s-1", "u-2") |
328 c.Assert(err, IsNil) | 328 c.Assert(err, IsNil) |
329 units, err = s.t.UnitKeys("s-0") | 329 units, err = s.t.UnitKeys("s-0") |
330 c.Assert(err, IsNil) | 330 c.Assert(err, IsNil) |
331 » c.Assert(units, Equals, []string{"u-0", "u-1"}) | 331 » c.Assert(units, DeepEquals, []string{"u-0", "u-1"}) |
332 units, err = s.t.UnitKeys("s-1") | 332 units, err = s.t.UnitKeys("s-1") |
333 c.Assert(err, IsNil) | 333 c.Assert(err, IsNil) |
334 » c.Assert(units, Equals, []string{"u-2"}) | 334 » c.Assert(units, DeepEquals, []string{"u-2"}) |
335 } | 335 } |
336 | 336 |
337 func (s TopologySuite) TestUnitKeysWithNonExistingService(c *C) { | 337 func (s TopologySuite) TestUnitKeysWithNonExistingService(c *C) { |
338 // Check if the retrieving of unit keys from a non-existing | 338 // Check if the retrieving of unit keys from a non-existing |
339 // service fails correctly. | 339 // service fails correctly. |
340 _, err := s.t.UnitKeys("s-0") | 340 _, err := s.t.UnitKeys("s-0") |
341 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) | 341 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) |
342 } | 342 } |
343 | 343 |
344 func (s TopologySuite) TestHasUnit(c *C) { | 344 func (s TopologySuite) TestHasUnit(c *C) { |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
470 func (s *ConfigNodeSuite) TearDownTest(c *C) { | 470 func (s *ConfigNodeSuite) TearDownTest(c *C) { |
471 // Delete possible nodes, ignore errors. | 471 // Delete possible nodes, ignore errors. |
472 zkRemoveTree(s.zkConn, s.path) | 472 zkRemoveTree(s.zkConn, s.path) |
473 s.zkConn.Close() | 473 s.zkConn.Close() |
474 } | 474 } |
475 | 475 |
476 func (s ConfigNodeSuite) TestCreateEmptyConfigNode(c *C) { | 476 func (s ConfigNodeSuite) TestCreateEmptyConfigNode(c *C) { |
477 // Check that creating an empty node works correctly. | 477 // Check that creating an empty node works correctly. |
478 node, err := createConfigNode(s.zkConn, s.path, nil) | 478 node, err := createConfigNode(s.zkConn, s.path, nil) |
479 c.Assert(err, IsNil) | 479 c.Assert(err, IsNil) |
480 » c.Assert(node.Keys(), Equals, []string{}) | 480 » c.Assert(node.Keys(), DeepEquals, []string{}) |
481 } | 481 } |
482 | 482 |
483 func (s ConfigNodeSuite) TestReadWithoutWrite(c *C) { | 483 func (s ConfigNodeSuite) TestReadWithoutWrite(c *C) { |
484 // Check reading without writing. | 484 // Check reading without writing. |
485 node, err := readConfigNode(s.zkConn, s.path) | 485 node, err := readConfigNode(s.zkConn, s.path) |
486 c.Assert(err, IsNil) | 486 c.Assert(err, IsNil) |
487 c.Assert(node, Not(IsNil)) | 487 c.Assert(node, Not(IsNil)) |
488 } | 488 } |
489 | 489 |
490 func (s ConfigNodeSuite) TestSetWithoutWrite(c *C) { | 490 func (s ConfigNodeSuite) TestSetWithoutWrite(c *C) { |
491 // Check that config values can be set. | 491 // Check that config values can be set. |
492 _, err := s.zkConn.Create(s.path, "", 0, zkPermAll) | 492 _, err := s.zkConn.Create(s.path, "", 0, zkPermAll) |
493 c.Assert(err, IsNil) | 493 c.Assert(err, IsNil) |
494 node, err := readConfigNode(s.zkConn, s.path) | 494 node, err := readConfigNode(s.zkConn, s.path) |
495 c.Assert(err, IsNil) | 495 c.Assert(err, IsNil) |
496 options := map[string]interface{}{"alpha": "beta", "one": 1} | 496 options := map[string]interface{}{"alpha": "beta", "one": 1} |
497 node.Update(options) | 497 node.Update(options) |
498 » c.Assert(node.Map(), Equals, options) | 498 » c.Assert(node.Map(), DeepEquals, options) |
499 // Node data has to be empty. | 499 // Node data has to be empty. |
500 yaml, _, err := s.zkConn.Get("/config") | 500 yaml, _, err := s.zkConn.Get("/config") |
501 c.Assert(err, IsNil) | 501 c.Assert(err, IsNil) |
502 c.Assert(yaml, Equals, "") | 502 c.Assert(yaml, Equals, "") |
503 } | 503 } |
504 | 504 |
505 func (s ConfigNodeSuite) TestSetWithWrite(c *C) { | 505 func (s ConfigNodeSuite) TestSetWithWrite(c *C) { |
506 // Check that write updates the local and the ZooKeeper state. | 506 // Check that write updates the local and the ZooKeeper state. |
507 node, err := readConfigNode(s.zkConn, s.path) | 507 node, err := readConfigNode(s.zkConn, s.path) |
508 c.Assert(err, IsNil) | 508 c.Assert(err, IsNil) |
509 options := map[string]interface{}{"alpha": "beta", "one": 1} | 509 options := map[string]interface{}{"alpha": "beta", "one": 1} |
510 node.Update(options) | 510 node.Update(options) |
511 changes, err := node.Write() | 511 changes, err := node.Write() |
512 c.Assert(err, IsNil) | 512 c.Assert(err, IsNil) |
513 » c.Assert(changes, Equals, []ItemChange{ | 513 » c.Assert(changes, DeepEquals, []ItemChange{ |
514 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 514 » » {ItemAdded, "alpha", nil, "beta"}, |
515 » » ItemChange{ItemAdded, "one", nil, 1}, | 515 » » {ItemAdded, "one", nil, 1}, |
516 }) | 516 }) |
517 // Check local state. | 517 // Check local state. |
518 » c.Assert(node.Map(), Equals, options) | 518 » c.Assert(node.Map(), DeepEquals, options) |
519 // Check ZooKeeper state. | 519 // Check ZooKeeper state. |
520 yaml, _, err := s.zkConn.Get(s.path) | 520 yaml, _, err := s.zkConn.Get(s.path) |
521 c.Assert(err, IsNil) | 521 c.Assert(err, IsNil) |
522 zkData := make(map[string]interface{}) | 522 zkData := make(map[string]interface{}) |
523 err = goyaml.Unmarshal([]byte(yaml), zkData) | 523 err = goyaml.Unmarshal([]byte(yaml), zkData) |
524 » c.Assert(zkData, Equals, options) | 524 » c.Assert(zkData, DeepEquals, options) |
525 } | 525 } |
526 | 526 |
527 func (s ConfigNodeSuite) TestConflictOnSet(c *C) { | 527 func (s ConfigNodeSuite) TestConflictOnSet(c *C) { |
528 // Check version conflict errors. | 528 // Check version conflict errors. |
529 nodeOne, err := readConfigNode(s.zkConn, s.path) | 529 nodeOne, err := readConfigNode(s.zkConn, s.path) |
530 c.Assert(err, IsNil) | 530 c.Assert(err, IsNil) |
531 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 531 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
532 c.Assert(err, IsNil) | 532 c.Assert(err, IsNil) |
533 | 533 |
534 optionsOld := map[string]interface{}{"alpha": "beta", "one": 1} | 534 optionsOld := map[string]interface{}{"alpha": "beta", "one": 1} |
535 nodeOne.Update(optionsOld) | 535 nodeOne.Update(optionsOld) |
536 nodeOne.Write() | 536 nodeOne.Write() |
537 | 537 |
538 nodeTwo.Update(optionsOld) | 538 nodeTwo.Update(optionsOld) |
539 changes, err := nodeTwo.Write() | 539 changes, err := nodeTwo.Write() |
540 c.Assert(err, IsNil) | 540 c.Assert(err, IsNil) |
541 » c.Assert(changes, Equals, []ItemChange{ | 541 » c.Assert(changes, DeepEquals, []ItemChange{ |
542 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 542 » » {ItemAdded, "alpha", nil, "beta"}, |
543 » » ItemChange{ItemAdded, "one", nil, 1}, | 543 » » {ItemAdded, "one", nil, 1}, |
544 }) | 544 }) |
545 | 545 |
546 // First test node one. | 546 // First test node one. |
547 » c.Assert(nodeOne.Map(), Equals, optionsOld) | 547 » c.Assert(nodeOne.Map(), DeepEquals, optionsOld) |
548 | 548 |
549 // Write on node one. | 549 // Write on node one. |
550 optionsNew := map[string]interface{}{"alpha": "gamma", "one": "two"} | 550 optionsNew := map[string]interface{}{"alpha": "gamma", "one": "two"} |
551 nodeOne.Update(optionsNew) | 551 nodeOne.Update(optionsNew) |
552 changes, err = nodeOne.Write() | 552 changes, err = nodeOne.Write() |
553 c.Assert(err, IsNil) | 553 c.Assert(err, IsNil) |
554 » c.Assert(changes, Equals, []ItemChange{ | 554 » c.Assert(changes, DeepEquals, []ItemChange{ |
555 » » ItemChange{ItemModified, "alpha", "beta", "gamma"}, | 555 » » {ItemModified, "alpha", "beta", "gamma"}, |
556 » » ItemChange{ItemModified, "one", 1, "two"}, | 556 » » {ItemModified, "one", 1, "two"}, |
557 }) | 557 }) |
558 | 558 |
559 // Verify that node one reports as expected. | 559 // Verify that node one reports as expected. |
560 » c.Assert(nodeOne.Map(), Equals, optionsNew) | 560 » c.Assert(nodeOne.Map(), DeepEquals, optionsNew) |
561 | 561 |
562 // Verify that node two has still the old data. | 562 // Verify that node two has still the old data. |
563 » c.Assert(nodeTwo.Map(), Equals, optionsOld) | 563 » c.Assert(nodeTwo.Map(), DeepEquals, optionsOld) |
564 | 564 |
565 // Now issue a Set/Write from node two. This will | 565 // Now issue a Set/Write from node two. This will |
566 // merge the data deleting 'one' and updating | 566 // merge the data deleting 'one' and updating |
567 // other values. | 567 // other values. |
568 optionsMerge := map[string]interface{}{"alpha": "cappa", "new": "next"} | 568 optionsMerge := map[string]interface{}{"alpha": "cappa", "new": "next"} |
569 nodeTwo.Update(optionsMerge) | 569 nodeTwo.Update(optionsMerge) |
570 nodeTwo.Delete("one") | 570 nodeTwo.Delete("one") |
571 | 571 |
572 expected := map[string]interface{}{"alpha": "cappa", "new": "next"} | 572 expected := map[string]interface{}{"alpha": "cappa", "new": "next"} |
573 changes, err = nodeTwo.Write() | 573 changes, err = nodeTwo.Write() |
574 c.Assert(err, IsNil) | 574 c.Assert(err, IsNil) |
575 » c.Assert(changes, Equals, []ItemChange{ | 575 » c.Assert(changes, DeepEquals, []ItemChange{ |
576 » » ItemChange{ItemModified, "alpha", "beta", "cappa"}, | 576 » » {ItemModified, "alpha", "beta", "cappa"}, |
577 » » ItemChange{ItemAdded, "new", nil, "next"}, | 577 » » {ItemAdded, "new", nil, "next"}, |
578 » » ItemChange{ItemDeleted, "one", 1, nil}, | 578 » » {ItemDeleted, "one", 1, nil}, |
579 » }) | 579 » }) |
580 » c.Assert(expected, Equals, nodeTwo.Map()) | 580 » c.Assert(expected, DeepEquals, nodeTwo.Map()) |
581 | 581 |
582 // But node one still reflects the former data. | 582 // But node one still reflects the former data. |
583 » c.Assert(nodeOne.Map(), Equals, optionsNew) | 583 » c.Assert(nodeOne.Map(), DeepEquals, optionsNew) |
584 } | 584 } |
585 | 585 |
586 func (s ConfigNodeSuite) TestSetItem(c *C) { | 586 func (s ConfigNodeSuite) TestSetItem(c *C) { |
587 // Check that Set works as expected. | 587 // Check that Set works as expected. |
588 node, err := readConfigNode(s.zkConn, s.path) | 588 node, err := readConfigNode(s.zkConn, s.path) |
589 c.Assert(err, IsNil) | 589 c.Assert(err, IsNil) |
590 options := map[string]interface{}{"alpha": "beta", "one": 1} | 590 options := map[string]interface{}{"alpha": "beta", "one": 1} |
591 node.Set("alpha", "beta") | 591 node.Set("alpha", "beta") |
592 node.Set("one", 1) | 592 node.Set("one", 1) |
593 changes, err := node.Write() | 593 changes, err := node.Write() |
594 c.Assert(err, IsNil) | 594 c.Assert(err, IsNil) |
595 » c.Assert(changes, Equals, []ItemChange{ | 595 » c.Assert(changes, DeepEquals, []ItemChange{ |
596 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 596 » » {ItemAdded, "alpha", nil, "beta"}, |
597 » » ItemChange{ItemAdded, "one", nil, 1}, | 597 » » {ItemAdded, "one", nil, 1}, |
598 }) | 598 }) |
599 // Check local state. | 599 // Check local state. |
600 » c.Assert(node.Map(), Equals, options) | 600 » c.Assert(node.Map(), DeepEquals, options) |
601 // Check ZooKeeper state. | 601 // Check ZooKeeper state. |
602 yaml, _, err := s.zkConn.Get(s.path) | 602 yaml, _, err := s.zkConn.Get(s.path) |
603 c.Assert(err, IsNil) | 603 c.Assert(err, IsNil) |
604 zkData := make(map[string]interface{}) | 604 zkData := make(map[string]interface{}) |
605 err = goyaml.Unmarshal([]byte(yaml), zkData) | 605 err = goyaml.Unmarshal([]byte(yaml), zkData) |
606 » c.Assert(zkData, Equals, options) | 606 » c.Assert(zkData, DeepEquals, options) |
607 } | 607 } |
608 | 608 |
609 func (s ConfigNodeSuite) TestMultipleReads(c *C) { | 609 func (s ConfigNodeSuite) TestMultipleReads(c *C) { |
610 // Check that reads without writes always resets the data. | 610 // Check that reads without writes always resets the data. |
611 nodeOne, err := readConfigNode(s.zkConn, s.path) | 611 nodeOne, err := readConfigNode(s.zkConn, s.path) |
612 c.Assert(err, IsNil) | 612 c.Assert(err, IsNil) |
613 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) | 613 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) |
614 value, ok := nodeOne.Get("alpha") | 614 value, ok := nodeOne.Get("alpha") |
615 c.Assert(ok, Equals, true) | 615 c.Assert(ok, Equals, true) |
616 c.Assert(value, Equals, "beta") | 616 c.Assert(value, Equals, "beta") |
617 value, ok = nodeOne.Get("foo") | 617 value, ok = nodeOne.Get("foo") |
618 c.Assert(ok, Equals, true) | 618 c.Assert(ok, Equals, true) |
619 c.Assert(value, Equals, "bar") | 619 c.Assert(value, Equals, "bar") |
620 value, ok = nodeOne.Get("baz") | 620 value, ok = nodeOne.Get("baz") |
621 c.Assert(ok, Equals, false) | 621 c.Assert(ok, Equals, false) |
622 | 622 |
623 // A read resets the data to the empty state. | 623 // A read resets the data to the empty state. |
624 err = nodeOne.Read() | 624 err = nodeOne.Read() |
625 c.Assert(err, IsNil) | 625 c.Assert(err, IsNil) |
626 » c.Assert(nodeOne.Map(), Equals, map[string]interface{}{}) | 626 » c.Assert(nodeOne.Map(), DeepEquals, map[string]interface{}{}) |
627 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) | 627 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) |
628 changes, err := nodeOne.Write() | 628 changes, err := nodeOne.Write() |
629 c.Assert(err, IsNil) | 629 c.Assert(err, IsNil) |
630 » c.Assert(changes, Equals, []ItemChange{ | 630 » c.Assert(changes, DeepEquals, []ItemChange{ |
631 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 631 » » {ItemAdded, "alpha", nil, "beta"}, |
632 » » ItemChange{ItemAdded, "foo", nil, "bar"}, | 632 » » {ItemAdded, "foo", nil, "bar"}, |
633 }) | 633 }) |
634 | 634 |
635 // A write retains the newly set values. | 635 // A write retains the newly set values. |
636 value, ok = nodeOne.Get("alpha") | 636 value, ok = nodeOne.Get("alpha") |
637 c.Assert(ok, Equals, true) | 637 c.Assert(ok, Equals, true) |
638 c.Assert(value, Equals, "beta") | 638 c.Assert(value, Equals, "beta") |
639 value, ok = nodeOne.Get("foo") | 639 value, ok = nodeOne.Get("foo") |
640 c.Assert(ok, Equals, true) | 640 c.Assert(ok, Equals, true) |
641 c.Assert(value, Equals, "bar") | 641 c.Assert(value, Equals, "bar") |
642 | 642 |
643 // Now get another state instance and change ZooKeeper state. | 643 // Now get another state instance and change ZooKeeper state. |
644 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 644 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
645 c.Assert(err, IsNil) | 645 c.Assert(err, IsNil) |
646 nodeTwo.Update(map[string]interface{}{"foo": "different"}) | 646 nodeTwo.Update(map[string]interface{}{"foo": "different"}) |
647 changes, err = nodeTwo.Write() | 647 changes, err = nodeTwo.Write() |
648 c.Assert(err, IsNil) | 648 c.Assert(err, IsNil) |
649 » c.Assert(changes, Equals, []ItemChange{ | 649 » c.Assert(changes, DeepEquals, []ItemChange{ |
650 » » ItemChange{ItemModified, "foo", "bar", "different"}, | 650 » » {ItemModified, "foo", "bar", "different"}, |
651 }) | 651 }) |
652 | 652 |
653 // This should pull in the new state into node one. | 653 // This should pull in the new state into node one. |
654 err = nodeOne.Read() | 654 err = nodeOne.Read() |
655 c.Assert(err, IsNil) | 655 c.Assert(err, IsNil) |
656 value, ok = nodeOne.Get("alpha") | 656 value, ok = nodeOne.Get("alpha") |
657 c.Assert(ok, Equals, true) | 657 c.Assert(ok, Equals, true) |
658 c.Assert(value, Equals, "beta") | 658 c.Assert(value, Equals, "beta") |
659 value, ok = nodeOne.Get("foo") | 659 value, ok = nodeOne.Get("foo") |
660 c.Assert(ok, Equals, true) | 660 c.Assert(ok, Equals, true) |
661 c.Assert(value, Equals, "different") | 661 c.Assert(value, Equals, "different") |
662 } | 662 } |
663 | 663 |
664 func (s ConfigNodeSuite) TestDeleteEmptiesState(c *C) { | 664 func (s ConfigNodeSuite) TestDeleteEmptiesState(c *C) { |
665 // Check that delete creates an empty state. | 665 // Check that delete creates an empty state. |
666 node, err := readConfigNode(s.zkConn, s.path) | 666 node, err := readConfigNode(s.zkConn, s.path) |
667 c.Assert(err, IsNil) | 667 c.Assert(err, IsNil) |
668 node.Set("a", "foo") | 668 node.Set("a", "foo") |
669 changes, err := node.Write() | 669 changes, err := node.Write() |
670 c.Assert(err, IsNil) | 670 c.Assert(err, IsNil) |
671 » c.Assert(changes, Equals, []ItemChange{ | 671 » c.Assert(changes, DeepEquals, []ItemChange{ |
672 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 672 » » {ItemAdded, "a", nil, "foo"}, |
673 }) | 673 }) |
674 node.Delete("a") | 674 node.Delete("a") |
675 changes, err = node.Write() | 675 changes, err = node.Write() |
676 c.Assert(err, IsNil) | 676 c.Assert(err, IsNil) |
677 » c.Assert(changes, Equals, []ItemChange{ | 677 » c.Assert(changes, DeepEquals, []ItemChange{ |
678 » » ItemChange{ItemDeleted, "a", "foo", nil}, | 678 » » {ItemDeleted, "a", "foo", nil}, |
679 » }) | 679 » }) |
680 » c.Assert(node.Map(), Equals, map[string]interface{}{}) | 680 » c.Assert(node.Map(), DeepEquals, map[string]interface{}{}) |
681 } | 681 } |
682 | 682 |
683 func (s ConfigNodeSuite) TestReadResync(c *C) { | 683 func (s ConfigNodeSuite) TestReadResync(c *C) { |
684 // Check that read pulls the data into the node. | 684 // Check that read pulls the data into the node. |
685 nodeOne, err := readConfigNode(s.zkConn, s.path) | 685 nodeOne, err := readConfigNode(s.zkConn, s.path) |
686 c.Assert(err, IsNil) | 686 c.Assert(err, IsNil) |
687 nodeOne.Set("a", "foo") | 687 nodeOne.Set("a", "foo") |
688 changes, err := nodeOne.Write() | 688 changes, err := nodeOne.Write() |
689 c.Assert(err, IsNil) | 689 c.Assert(err, IsNil) |
690 » c.Assert(changes, Equals, []ItemChange{ | 690 » c.Assert(changes, DeepEquals, []ItemChange{ |
691 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 691 » » {ItemAdded, "a", nil, "foo"}, |
692 }) | 692 }) |
693 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 693 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
694 c.Assert(err, IsNil) | 694 c.Assert(err, IsNil) |
695 nodeTwo.Delete("a") | 695 nodeTwo.Delete("a") |
696 changes, err = nodeTwo.Write() | 696 changes, err = nodeTwo.Write() |
697 c.Assert(err, IsNil) | 697 c.Assert(err, IsNil) |
698 » c.Assert(changes, Equals, []ItemChange{ | 698 » c.Assert(changes, DeepEquals, []ItemChange{ |
699 » » ItemChange{ItemDeleted, "a", "foo", nil}, | 699 » » {ItemDeleted, "a", "foo", nil}, |
700 }) | 700 }) |
701 nodeTwo.Set("a", "bar") | 701 nodeTwo.Set("a", "bar") |
702 changes, err = nodeTwo.Write() | 702 changes, err = nodeTwo.Write() |
703 c.Assert(err, IsNil) | 703 c.Assert(err, IsNil) |
704 » c.Assert(changes, Equals, []ItemChange{ | 704 » c.Assert(changes, DeepEquals, []ItemChange{ |
705 » » ItemChange{ItemAdded, "a", nil, "bar"}, | 705 » » {ItemAdded, "a", nil, "bar"}, |
706 }) | 706 }) |
707 // Read of node one should pick up the new value. | 707 // Read of node one should pick up the new value. |
708 err = nodeOne.Read() | 708 err = nodeOne.Read() |
709 c.Assert(err, IsNil) | 709 c.Assert(err, IsNil) |
710 value, ok := nodeOne.Get("a") | 710 value, ok := nodeOne.Get("a") |
711 c.Assert(ok, Equals, true) | 711 c.Assert(ok, Equals, true) |
712 c.Assert(value, Equals, "bar") | 712 c.Assert(value, Equals, "bar") |
713 } | 713 } |
714 | 714 |
715 func (s ConfigNodeSuite) TestMultipleWrites(c *C) { | 715 func (s ConfigNodeSuite) TestMultipleWrites(c *C) { |
716 // Check that multiple writes only do the right changes. | 716 // Check that multiple writes only do the right changes. |
717 node, err := readConfigNode(s.zkConn, s.path) | 717 node, err := readConfigNode(s.zkConn, s.path) |
718 c.Assert(err, IsNil) | 718 c.Assert(err, IsNil) |
719 node.Update(map[string]interface{}{"foo": "bar", "this": "that"}) | 719 node.Update(map[string]interface{}{"foo": "bar", "this": "that"}) |
720 changes, err := node.Write() | 720 changes, err := node.Write() |
721 c.Assert(err, IsNil) | 721 c.Assert(err, IsNil) |
722 » c.Assert(changes, Equals, []ItemChange{ | 722 » c.Assert(changes, DeepEquals, []ItemChange{ |
723 » » ItemChange{ItemAdded, "foo", nil, "bar"}, | 723 » » {ItemAdded, "foo", nil, "bar"}, |
724 » » ItemChange{ItemAdded, "this", nil, "that"}, | 724 » » {ItemAdded, "this", nil, "that"}, |
725 }) | 725 }) |
726 node.Delete("this") | 726 node.Delete("this") |
727 node.Set("another", "value") | 727 node.Set("another", "value") |
728 changes, err = node.Write() | 728 changes, err = node.Write() |
729 c.Assert(err, IsNil) | 729 c.Assert(err, IsNil) |
730 » c.Assert(changes, Equals, []ItemChange{ | 730 » c.Assert(changes, DeepEquals, []ItemChange{ |
731 » » ItemChange{ItemAdded, "another", nil, "value"}, | 731 » » {ItemAdded, "another", nil, "value"}, |
732 » » ItemChange{ItemDeleted, "this", "that", nil}, | 732 » » {ItemDeleted, "this", "that", nil}, |
733 }) | 733 }) |
734 | 734 |
735 expected := map[string]interface{}{"foo": "bar", "another": "value"} | 735 expected := map[string]interface{}{"foo": "bar", "another": "value"} |
736 » c.Assert(expected, Equals, node.Map()) | 736 » c.Assert(expected, DeepEquals, node.Map()) |
737 | 737 |
738 changes, err = node.Write() | 738 changes, err = node.Write() |
739 c.Assert(err, IsNil) | 739 c.Assert(err, IsNil) |
740 » c.Assert(changes, Equals, []ItemChange{}) | 740 » c.Assert(changes, DeepEquals, []ItemChange{}) |
741 | 741 |
742 err = node.Read() | 742 err = node.Read() |
743 c.Assert(err, IsNil) | 743 c.Assert(err, IsNil) |
744 » c.Assert(expected, Equals, node.Map()) | 744 » c.Assert(expected, DeepEquals, node.Map()) |
745 | 745 |
746 changes, err = node.Write() | 746 changes, err = node.Write() |
747 c.Assert(err, IsNil) | 747 c.Assert(err, IsNil) |
748 » c.Assert(changes, Equals, []ItemChange{}) | 748 » c.Assert(changes, DeepEquals, []ItemChange{}) |
749 } | 749 } |
750 | 750 |
751 func (s ConfigNodeSuite) TestWriteTwice(c *C) { | 751 func (s ConfigNodeSuite) TestWriteTwice(c *C) { |
752 // Check the correct writing into a node by two config nodes. | 752 // Check the correct writing into a node by two config nodes. |
753 nodeOne, err := readConfigNode(s.zkConn, s.path) | 753 nodeOne, err := readConfigNode(s.zkConn, s.path) |
754 c.Assert(err, IsNil) | 754 c.Assert(err, IsNil) |
755 nodeOne.Set("a", "foo") | 755 nodeOne.Set("a", "foo") |
756 changes, err := nodeOne.Write() | 756 changes, err := nodeOne.Write() |
757 c.Assert(err, IsNil) | 757 c.Assert(err, IsNil) |
758 » c.Assert(changes, Equals, []ItemChange{ | 758 » c.Assert(changes, DeepEquals, []ItemChange{ |
759 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 759 » » {ItemAdded, "a", nil, "foo"}, |
760 }) | 760 }) |
761 | 761 |
762 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 762 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
763 c.Assert(err, IsNil) | 763 c.Assert(err, IsNil) |
764 nodeTwo.Set("a", "bar") | 764 nodeTwo.Set("a", "bar") |
765 changes, err = nodeTwo.Write() | 765 changes, err = nodeTwo.Write() |
766 c.Assert(err, IsNil) | 766 c.Assert(err, IsNil) |
767 » c.Assert(changes, Equals, []ItemChange{ | 767 » c.Assert(changes, DeepEquals, []ItemChange{ |
768 » » ItemChange{ItemModified, "a", "foo", "bar"}, | 768 » » {ItemModified, "a", "foo", "bar"}, |
769 }) | 769 }) |
770 | 770 |
771 // Shouldn't write again. Changes were already | 771 // Shouldn't write again. Changes were already |
772 // flushed and acted upon by other parties. | 772 // flushed and acted upon by other parties. |
773 changes, err = nodeOne.Write() | 773 changes, err = nodeOne.Write() |
774 c.Assert(err, IsNil) | 774 c.Assert(err, IsNil) |
775 » c.Assert(changes, Equals, []ItemChange{}) | 775 » c.Assert(changes, DeepEquals, []ItemChange{}) |
776 | 776 |
777 err = nodeOne.Read() | 777 err = nodeOne.Read() |
778 c.Assert(err, IsNil) | 778 c.Assert(err, IsNil) |
779 » c.Assert(nodeOne, Equals, nodeTwo) | 779 » c.Assert(nodeOne, DeepEquals, nodeTwo) |
780 } | 780 } |
781 | 781 |
782 type QuoteSuite struct{} | 782 type QuoteSuite struct{} |
783 | 783 |
784 var _ = Suite(&QuoteSuite{}) | 784 var _ = Suite(&QuoteSuite{}) |
785 | 785 |
786 func (s QuoteSuite) TestUnmodified(c *C) { | 786 func (s QuoteSuite) TestUnmodified(c *C) { |
787 // Check that a string containig only valid | 787 // Check that a string containig only valid |
788 // chars stays unmodified. | 788 // chars stays unmodified. |
789 in := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-" | 789 in := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-" |
790 out := Quote(in) | 790 out := Quote(in) |
791 c.Assert(out, Equals, in) | 791 c.Assert(out, Equals, in) |
792 } | 792 } |
793 | 793 |
794 func (s QuoteSuite) TestQuote(c *C) { | 794 func (s QuoteSuite) TestQuote(c *C) { |
795 // Check that invalid chars are translated correctly. | 795 // Check that invalid chars are translated correctly. |
796 in := "hello_there/how'are~you-today.sir" | 796 in := "hello_there/how'are~you-today.sir" |
797 out := Quote(in) | 797 out := Quote(in) |
798 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir") | 798 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir") |
799 } | 799 } |
LEFT | RIGHT |