OLD | NEW |
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 | |
5 package state | 4 package state |
6 | 5 |
7 import ( | 6 import ( |
8 "fmt" | |
9 . "launchpad.net/gocheck" | 7 . "launchpad.net/gocheck" |
10 "launchpad.net/goyaml" | 8 "launchpad.net/goyaml" |
11 "launchpad.net/gozk/zookeeper" | 9 "launchpad.net/gozk/zookeeper" |
12 "testing" | |
13 ) | 10 ) |
14 | 11 |
15 // TestPackage integrates the tests into gotest. | |
16 func TestPackage(t *testing.T) { | |
17 TestingT(t) | |
18 } | |
19 | |
20 type TopologySuite struct { | 12 type TopologySuite struct { |
21 zkServer *zookeeper.Server | 13 zkServer *zookeeper.Server |
22 zkTestRoot string | 14 zkTestRoot string |
23 zkTestPort int | 15 zkTestPort int |
24 zkAddr string | 16 zkAddr string |
25 zkConn *zookeeper.Conn | 17 zkConn *zookeeper.Conn |
26 t *topology | 18 t *topology |
27 } | 19 } |
28 | 20 |
29 var _ = Suite(&TopologySuite{}) | 21 var _ = Suite(&TopologySuite{}) |
30 | 22 |
31 func (s *TopologySuite) SetUpSuite(c *C) { | |
32 var err error | |
33 s.zkTestRoot = c.MkDir() + "/zookeeper" | |
34 s.zkTestPort = 21812 | |
35 s.zkAddr = fmt.Sprint("localhost:", s.zkTestPort) | |
36 | |
37 s.zkServer, err = zookeeper.CreateServer(s.zkTestPort, s.zkTestRoot, "") | |
38 if err != nil { | |
39 c.Fatal("Cannot set up ZooKeeper server environment: ", err) | |
40 } | |
41 err = s.zkServer.Start() | |
42 if err != nil { | |
43 c.Fatal("Cannot start ZooKeeper server: ", err) | |
44 } | |
45 } | |
46 | |
47 func (s *TopologySuite) TearDownSuite(c *C) { | |
48 if s.zkServer != nil { | |
49 s.zkServer.Destroy() | |
50 } | |
51 } | |
52 | |
53 func (s *TopologySuite) SetUpTest(c *C) { | 23 func (s *TopologySuite) SetUpTest(c *C) { |
54 // Connect the server. | 24 // Connect the server. |
55 » _, s.zkConn = OpenAddr(c, s.zkAddr) | 25 » st, err := Open(&Info{ |
| 26 » » Addrs: []string{ZkAddr}, |
| 27 » }) |
| 28 » c.Assert(err, IsNil) |
| 29 » s.zkConn = ZkConn(st) |
56 // Read the toplogy. | 30 // Read the toplogy. |
57 var err error | |
58 s.t, err = readTopology(s.zkConn) | 31 s.t, err = readTopology(s.zkConn) |
59 c.Assert(err, IsNil) | 32 c.Assert(err, IsNil) |
60 } | 33 } |
61 | 34 |
62 func (s *TopologySuite) TearDownTest(c *C) { | 35 func (s *TopologySuite) TearDownTest(c *C) { |
63 // Delete possible nodes, ignore errors. | 36 // Delete possible nodes, ignore errors. |
64 zkRemoveTree(s.zkConn, "/topology") | 37 zkRemoveTree(s.zkConn, "/topology") |
65 s.zkConn.Close() | 38 s.zkConn.Close() |
66 } | 39 } |
67 | 40 |
68 func (s TopologySuite) TestAddMachine(c *C) { | 41 func (s TopologySuite) TestAddMachine(c *C) { |
69 // Check that adding machines works correctly. | 42 // Check that adding machines works correctly. |
70 err := s.t.AddMachine("m-0") | 43 err := s.t.AddMachine("m-0") |
71 c.Assert(err, IsNil) | 44 c.Assert(err, IsNil) |
72 err = s.t.AddMachine("m-1") | 45 err = s.t.AddMachine("m-1") |
73 c.Assert(err, IsNil) | 46 c.Assert(err, IsNil) |
74 keys := s.t.MachineKeys() | 47 keys := s.t.MachineKeys() |
75 » c.Assert(keys, Equals, []string{"m-0", "m-1"}) | 48 » c.Assert(keys, DeepEquals, []string{"m-0", "m-1"}) |
76 } | 49 } |
77 | 50 |
78 func (s TopologySuite) TestAddDuplicatedMachine(c *C) { | 51 func (s TopologySuite) TestAddDuplicatedMachine(c *C) { |
79 // Check that adding a duplicated machine by key fails. | 52 // Check that adding a duplicated machine by key fails. |
80 err := s.t.AddMachine("m-0") | 53 err := s.t.AddMachine("m-0") |
81 c.Assert(err, IsNil) | 54 c.Assert(err, IsNil) |
82 err = s.t.AddMachine("m-0") | 55 err = s.t.AddMachine("m-0") |
83 c.Assert(err, ErrorMatches, `attempted to add duplicated machine "m-0"`) | 56 c.Assert(err, ErrorMatches, `attempted to add duplicated machine "m-0"`) |
84 } | 57 } |
85 | 58 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 _, err = s.t.AddUnit("s-0", "u-1") | 95 _, err = s.t.AddUnit("s-0", "u-1") |
123 c.Assert(err, IsNil) | 96 c.Assert(err, IsNil) |
124 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0") | 97 err = s.t.AssignUnitToMachine("s-0", "u-1", "m-0") |
125 c.Assert(err, IsNil) | 98 c.Assert(err, IsNil) |
126 err = s.t.RemoveMachine("m-0") | 99 err = s.t.RemoveMachine("m-0") |
127 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`) |
128 } | 101 } |
129 | 102 |
130 func (s TopologySuite) TestMachineHasUnits(c *C) { | 103 func (s TopologySuite) TestMachineHasUnits(c *C) { |
131 // Check various ways a machine might or might not be assigned | 104 // Check various ways a machine might or might not be assigned |
132 » // to a unit.» | 105 » // to a unit. |
133 err := s.t.AddMachine("m-0") | 106 err := s.t.AddMachine("m-0") |
134 c.Assert(err, IsNil) | 107 c.Assert(err, IsNil) |
135 err = s.t.AddMachine("m-1") | 108 err = s.t.AddMachine("m-1") |
136 c.Assert(err, IsNil) | 109 c.Assert(err, IsNil) |
137 err = s.t.AddService("s-0", "wordpress") | 110 err = s.t.AddService("s-0", "wordpress") |
138 c.Assert(err, IsNil) | 111 c.Assert(err, IsNil) |
139 _, err = s.t.AddUnit("s-0", "u-0") | 112 _, err = s.t.AddUnit("s-0", "u-0") |
140 c.Assert(err, IsNil) | 113 c.Assert(err, IsNil) |
141 _, err = s.t.AddUnit("s-0", "u-1") | 114 _, err = s.t.AddUnit("s-0", "u-1") |
142 c.Assert(err, IsNil) | 115 c.Assert(err, IsNil) |
(...skipping 17 matching lines...) Expand all Loading... |
160 c.Assert(err, IsNil) | 133 c.Assert(err, IsNil) |
161 found = s.t.HasMachine("m-0") | 134 found = s.t.HasMachine("m-0") |
162 c.Assert(found, Equals, true) | 135 c.Assert(found, Equals, true) |
163 found = s.t.HasMachine("m-1") | 136 found = s.t.HasMachine("m-1") |
164 c.Assert(found, Equals, false) | 137 c.Assert(found, Equals, false) |
165 } | 138 } |
166 | 139 |
167 func (s TopologySuite) TestMachineKeys(c *C) { | 140 func (s TopologySuite) TestMachineKeys(c *C) { |
168 // Check that the retrieval of all services keys works correctly. | 141 // Check that the retrieval of all services keys works correctly. |
169 keys := s.t.MachineKeys() | 142 keys := s.t.MachineKeys() |
170 » c.Assert(keys, Equals, []string{}) | 143 » c.Assert(keys, DeepEquals, []string{}) |
171 err := s.t.AddMachine("m-0") | 144 err := s.t.AddMachine("m-0") |
172 c.Assert(err, IsNil) | 145 c.Assert(err, IsNil) |
173 err = s.t.AddMachine("m-1") | 146 err = s.t.AddMachine("m-1") |
174 c.Assert(err, IsNil) | 147 c.Assert(err, IsNil) |
175 keys = s.t.MachineKeys() | 148 keys = s.t.MachineKeys() |
176 » c.Assert(keys, Equals, []string{"m-0", "m-1"}) | 149 » c.Assert(keys, DeepEquals, []string{"m-0", "m-1"}) |
177 } | 150 } |
178 | 151 |
179 func (s TopologySuite) TestAddService(c *C) { | 152 func (s TopologySuite) TestAddService(c *C) { |
180 // Check that adding services works correctly. | 153 // Check that adding services works correctly. |
181 c.Assert(s.t.HasService("s-0"), Equals, false) | 154 c.Assert(s.t.HasService("s-0"), Equals, false) |
182 err := s.t.AddService("s-0", "wordpress") | 155 err := s.t.AddService("s-0", "wordpress") |
183 c.Assert(err, IsNil) | 156 c.Assert(err, IsNil) |
184 err = s.t.AddService("s-1", "mysql") | 157 err = s.t.AddService("s-1", "mysql") |
185 c.Assert(err, IsNil) | 158 c.Assert(err, IsNil) |
186 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... |
216 err = s.t.AddService("s-0", "wordpress") | 189 err = s.t.AddService("s-0", "wordpress") |
217 c.Assert(err, IsNil) | 190 c.Assert(err, IsNil) |
218 key, err = s.t.ServiceKey("wordpress") | 191 key, err = s.t.ServiceKey("wordpress") |
219 c.Assert(err, IsNil) | 192 c.Assert(err, IsNil) |
220 c.Assert(key, Equals, "s-0") | 193 c.Assert(key, Equals, "s-0") |
221 } | 194 } |
222 | 195 |
223 func (s TopologySuite) TestServiceKeys(c *C) { | 196 func (s TopologySuite) TestServiceKeys(c *C) { |
224 // Check that the retrieval of all services keys works correctly. | 197 // Check that the retrieval of all services keys works correctly. |
225 keys := s.t.ServiceKeys() | 198 keys := s.t.ServiceKeys() |
226 » c.Assert(keys, Equals, []string{}) | 199 » c.Assert(keys, DeepEquals, []string{}) |
227 err := s.t.AddService("s-0", "wordpress") | 200 err := s.t.AddService("s-0", "wordpress") |
228 c.Assert(err, IsNil) | 201 c.Assert(err, IsNil) |
229 err = s.t.AddService("s-1", "mysql") | 202 err = s.t.AddService("s-1", "mysql") |
230 c.Assert(err, IsNil) | 203 c.Assert(err, IsNil) |
231 keys = s.t.ServiceKeys() | 204 keys = s.t.ServiceKeys() |
232 » c.Assert(keys, Equals, []string{"s-0", "s-1"}) | 205 » c.Assert(keys, DeepEquals, []string{"s-0", "s-1"}) |
233 } | 206 } |
234 | 207 |
235 func (s TopologySuite) TestServiceName(c *C) { | 208 func (s TopologySuite) TestServiceName(c *C) { |
236 // Check that the name retrieval for a service name works correctly. | 209 // Check that the name retrieval for a service name works correctly. |
237 name, err := s.t.ServiceName("s-0") | 210 name, err := s.t.ServiceName("s-0") |
238 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) | 211 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) |
239 err = s.t.AddService("s-0", "wordpress") | 212 err = s.t.AddService("s-0", "wordpress") |
240 c.Assert(err, IsNil) | 213 c.Assert(err, IsNil) |
241 name, err = s.t.ServiceName("s-0") | 214 name, err = s.t.ServiceName("s-0") |
242 c.Assert(err, IsNil) | 215 c.Assert(err, IsNil) |
(...skipping 28 matching lines...) Expand all Loading... |
271 c.Assert(err, IsNil) | 244 c.Assert(err, IsNil) |
272 c.Assert(seq, Equals, 0) | 245 c.Assert(seq, Equals, 0) |
273 seq, err = s.t.AddUnit("s-0", "u-12") | 246 seq, err = s.t.AddUnit("s-0", "u-12") |
274 c.Assert(err, IsNil) | 247 c.Assert(err, IsNil) |
275 c.Assert(seq, Equals, 1) | 248 c.Assert(seq, Equals, 1) |
276 seq, err = s.t.AddUnit("s-1", "u-07") | 249 seq, err = s.t.AddUnit("s-1", "u-07") |
277 c.Assert(err, IsNil) | 250 c.Assert(err, IsNil) |
278 c.Assert(seq, Equals, 0) | 251 c.Assert(seq, Equals, 0) |
279 keys, err := s.t.UnitKeys("s-0") | 252 keys, err := s.t.UnitKeys("s-0") |
280 c.Assert(err, IsNil) | 253 c.Assert(err, IsNil) |
281 » c.Assert(keys, Equals, []string{"u-05", "u-12"}) | 254 » c.Assert(keys, DeepEquals, []string{"u-05", "u-12"}) |
282 keys, err = s.t.UnitKeys("s-1") | 255 keys, err = s.t.UnitKeys("s-1") |
283 c.Assert(err, IsNil) | 256 c.Assert(err, IsNil) |
284 » c.Assert(keys, Equals, []string{"u-07"}) | 257 » c.Assert(keys, DeepEquals, []string{"u-07"}) |
285 } | 258 } |
286 | 259 |
287 func (s TopologySuite) TestGlobalUniqueUnitNames(c *C) { | 260 func (s TopologySuite) TestGlobalUniqueUnitNames(c *C) { |
288 // Check that even if the underlying service is destroyed | 261 // Check that even if the underlying service is destroyed |
289 // 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 |
290 // get a duplicate unit name. | 263 // get a duplicate unit name. |
291 err := s.t.AddService("s-0", "wordpress") | 264 err := s.t.AddService("s-0", "wordpress") |
292 c.Assert(err, IsNil) | 265 c.Assert(err, IsNil) |
293 seq, err := s.t.AddUnit("s-0", "u-0") | 266 seq, err := s.t.AddUnit("s-0", "u-0") |
294 c.Assert(err, IsNil) | 267 c.Assert(err, IsNil) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 } | 312 } |
340 | 313 |
341 func (s TopologySuite) TestUnitKeys(c *C) { | 314 func (s TopologySuite) TestUnitKeys(c *C) { |
342 // Check if registered units from a service are returned correctly. | 315 // Check if registered units from a service are returned correctly. |
343 err := s.t.AddService("s-0", "wordpress") | 316 err := s.t.AddService("s-0", "wordpress") |
344 c.Assert(err, IsNil) | 317 c.Assert(err, IsNil) |
345 err = s.t.AddService("s-1", "mysql") | 318 err = s.t.AddService("s-1", "mysql") |
346 c.Assert(err, IsNil) | 319 c.Assert(err, IsNil) |
347 units, err := s.t.UnitKeys("s-0") | 320 units, err := s.t.UnitKeys("s-0") |
348 c.Assert(err, IsNil) | 321 c.Assert(err, IsNil) |
349 » c.Assert(units, Equals, []string{}) | 322 » c.Assert(units, DeepEquals, []string{}) |
350 _, err = s.t.AddUnit("s-0", "u-0") | 323 _, err = s.t.AddUnit("s-0", "u-0") |
351 c.Assert(err, IsNil) | 324 c.Assert(err, IsNil) |
352 _, err = s.t.AddUnit("s-0", "u-1") | 325 _, err = s.t.AddUnit("s-0", "u-1") |
353 c.Assert(err, IsNil) | 326 c.Assert(err, IsNil) |
354 _, err = s.t.AddUnit("s-1", "u-2") | 327 _, err = s.t.AddUnit("s-1", "u-2") |
355 c.Assert(err, IsNil) | 328 c.Assert(err, IsNil) |
356 units, err = s.t.UnitKeys("s-0") | 329 units, err = s.t.UnitKeys("s-0") |
357 c.Assert(err, IsNil) | 330 c.Assert(err, IsNil) |
358 » c.Assert(units, Equals, []string{"u-0", "u-1"}) | 331 » c.Assert(units, DeepEquals, []string{"u-0", "u-1"}) |
359 units, err = s.t.UnitKeys("s-1") | 332 units, err = s.t.UnitKeys("s-1") |
360 c.Assert(err, IsNil) | 333 c.Assert(err, IsNil) |
361 » c.Assert(units, Equals, []string{"u-2"}) | 334 » c.Assert(units, DeepEquals, []string{"u-2"}) |
362 } | 335 } |
363 | 336 |
364 func (s TopologySuite) TestUnitKeysWithNonExistingService(c *C) { | 337 func (s TopologySuite) TestUnitKeysWithNonExistingService(c *C) { |
365 // Check if the retrieving of unit keys from a non-existing | 338 // Check if the retrieving of unit keys from a non-existing |
366 // service fails correctly. | 339 // service fails correctly. |
367 _, err := s.t.UnitKeys("s-0") | 340 _, err := s.t.UnitKeys("s-0") |
368 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) | 341 c.Assert(err, ErrorMatches, `service with key "s-0" not found`) |
369 } | 342 } |
370 | 343 |
371 func (s TopologySuite) TestHasUnit(c *C) { | 344 func (s TopologySuite) TestHasUnit(c *C) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
475 zkTestRoot string | 448 zkTestRoot string |
476 zkTestPort int | 449 zkTestPort int |
477 zkAddr string | 450 zkAddr string |
478 zkConn *zookeeper.Conn | 451 zkConn *zookeeper.Conn |
479 path string | 452 path string |
480 } | 453 } |
481 | 454 |
482 var _ = Suite(&ConfigNodeSuite{}) | 455 var _ = Suite(&ConfigNodeSuite{}) |
483 | 456 |
484 func (s *ConfigNodeSuite) SetUpSuite(c *C) { | 457 func (s *ConfigNodeSuite) SetUpSuite(c *C) { |
485 var err error | |
486 s.zkTestRoot = c.MkDir() + "/zookeeper" | |
487 s.zkTestPort = 21812 | |
488 s.zkAddr = fmt.Sprint("localhost:", s.zkTestPort) | |
489 s.path = "/config" | 458 s.path = "/config" |
490 | |
491 s.zkServer, err = zookeeper.CreateServer(s.zkTestPort, s.zkTestRoot, "") | |
492 if err != nil { | |
493 c.Fatal("Cannot set up ZooKeeper server environment: ", err) | |
494 } | |
495 err = s.zkServer.Start() | |
496 if err != nil { | |
497 c.Fatal("Cannot start ZooKeeper server: ", err) | |
498 } | |
499 } | |
500 | |
501 func (s *ConfigNodeSuite) TearDownSuite(c *C) { | |
502 if s.zkServer != nil { | |
503 s.zkServer.Destroy() | |
504 } | |
505 } | 459 } |
506 | 460 |
507 func (s *ConfigNodeSuite) SetUpTest(c *C) { | 461 func (s *ConfigNodeSuite) SetUpTest(c *C) { |
508 » _, s.zkConn = OpenAddr(c, s.zkAddr) | 462 » // Connect the server. |
| 463 » st, err := Open(&Info{ |
| 464 » » Addrs: []string{ZkAddr}, |
| 465 » }) |
| 466 » c.Assert(err, IsNil) |
| 467 » s.zkConn = ZkConn(st) |
509 } | 468 } |
510 | 469 |
511 func (s *ConfigNodeSuite) TearDownTest(c *C) { | 470 func (s *ConfigNodeSuite) TearDownTest(c *C) { |
512 // Delete possible nodes, ignore errors. | 471 // Delete possible nodes, ignore errors. |
513 zkRemoveTree(s.zkConn, s.path) | 472 zkRemoveTree(s.zkConn, s.path) |
514 s.zkConn.Close() | 473 s.zkConn.Close() |
515 } | 474 } |
516 | 475 |
517 func (s ConfigNodeSuite) TestCreateEmptyConfigNode(c *C) { | 476 func (s ConfigNodeSuite) TestCreateEmptyConfigNode(c *C) { |
518 // Check that creating an empty node works correctly. | 477 // Check that creating an empty node works correctly. |
519 node, err := createConfigNode(s.zkConn, s.path, nil) | 478 node, err := createConfigNode(s.zkConn, s.path, nil) |
520 c.Assert(err, IsNil) | 479 c.Assert(err, IsNil) |
521 » c.Assert(node.Keys(), Equals, []string{}) | 480 » c.Assert(node.Keys(), DeepEquals, []string{}) |
522 } | 481 } |
523 | 482 |
524 func (s ConfigNodeSuite) TestReadWithoutWrite(c *C) { | 483 func (s ConfigNodeSuite) TestReadWithoutWrite(c *C) { |
525 // Check reading without writing. | 484 // Check reading without writing. |
526 node, err := readConfigNode(s.zkConn, s.path) | 485 node, err := readConfigNode(s.zkConn, s.path) |
527 c.Assert(err, IsNil) | 486 c.Assert(err, IsNil) |
528 c.Assert(node, Not(IsNil)) | 487 c.Assert(node, Not(IsNil)) |
529 } | 488 } |
530 | 489 |
531 func (s ConfigNodeSuite) TestSetWithoutWrite(c *C) { | 490 func (s ConfigNodeSuite) TestSetWithoutWrite(c *C) { |
532 // Check that config values can be set. | 491 // Check that config values can be set. |
533 _, err := s.zkConn.Create(s.path, "", 0, zkPermAll) | 492 _, err := s.zkConn.Create(s.path, "", 0, zkPermAll) |
534 c.Assert(err, IsNil) | 493 c.Assert(err, IsNil) |
535 node, err := readConfigNode(s.zkConn, s.path) | 494 node, err := readConfigNode(s.zkConn, s.path) |
536 c.Assert(err, IsNil) | 495 c.Assert(err, IsNil) |
537 options := map[string]interface{}{"alpha": "beta", "one": 1} | 496 options := map[string]interface{}{"alpha": "beta", "one": 1} |
538 node.Update(options) | 497 node.Update(options) |
539 » c.Assert(node.Map(), Equals, options) | 498 » c.Assert(node.Map(), DeepEquals, options) |
540 // Node data has to be empty. | 499 // Node data has to be empty. |
541 yaml, _, err := s.zkConn.Get("/config") | 500 yaml, _, err := s.zkConn.Get("/config") |
542 c.Assert(err, IsNil) | 501 c.Assert(err, IsNil) |
543 c.Assert(yaml, Equals, "") | 502 c.Assert(yaml, Equals, "") |
544 } | 503 } |
545 | 504 |
546 func (s ConfigNodeSuite) TestSetWithWrite(c *C) { | 505 func (s ConfigNodeSuite) TestSetWithWrite(c *C) { |
547 // Check that write updates the local and the ZooKeeper state. | 506 // Check that write updates the local and the ZooKeeper state. |
548 node, err := readConfigNode(s.zkConn, s.path) | 507 node, err := readConfigNode(s.zkConn, s.path) |
549 c.Assert(err, IsNil) | 508 c.Assert(err, IsNil) |
550 options := map[string]interface{}{"alpha": "beta", "one": 1} | 509 options := map[string]interface{}{"alpha": "beta", "one": 1} |
551 node.Update(options) | 510 node.Update(options) |
552 changes, err := node.Write() | 511 changes, err := node.Write() |
553 c.Assert(err, IsNil) | 512 c.Assert(err, IsNil) |
554 » c.Assert(changes, Equals, []ItemChange{ | 513 » c.Assert(changes, DeepEquals, []ItemChange{ |
555 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 514 » » {ItemAdded, "alpha", nil, "beta"}, |
556 » » ItemChange{ItemAdded, "one", nil, 1}, | 515 » » {ItemAdded, "one", nil, 1}, |
557 }) | 516 }) |
558 // Check local state. | 517 // Check local state. |
559 » c.Assert(node.Map(), Equals, options) | 518 » c.Assert(node.Map(), DeepEquals, options) |
560 // Check ZooKeeper state. | 519 // Check ZooKeeper state. |
561 yaml, _, err := s.zkConn.Get(s.path) | 520 yaml, _, err := s.zkConn.Get(s.path) |
562 c.Assert(err, IsNil) | 521 c.Assert(err, IsNil) |
563 zkData := make(map[string]interface{}) | 522 zkData := make(map[string]interface{}) |
564 err = goyaml.Unmarshal([]byte(yaml), zkData) | 523 err = goyaml.Unmarshal([]byte(yaml), zkData) |
565 » c.Assert(zkData, Equals, options) | 524 » c.Assert(zkData, DeepEquals, options) |
566 } | 525 } |
567 | 526 |
568 func (s ConfigNodeSuite) TestConflictOnSet(c *C) { | 527 func (s ConfigNodeSuite) TestConflictOnSet(c *C) { |
569 // Check version conflict errors. | 528 // Check version conflict errors. |
570 nodeOne, err := readConfigNode(s.zkConn, s.path) | 529 nodeOne, err := readConfigNode(s.zkConn, s.path) |
571 c.Assert(err, IsNil) | 530 c.Assert(err, IsNil) |
572 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 531 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
573 c.Assert(err, IsNil) | 532 c.Assert(err, IsNil) |
574 | 533 |
575 optionsOld := map[string]interface{}{"alpha": "beta", "one": 1} | 534 optionsOld := map[string]interface{}{"alpha": "beta", "one": 1} |
576 nodeOne.Update(optionsOld) | 535 nodeOne.Update(optionsOld) |
577 nodeOne.Write() | 536 nodeOne.Write() |
578 | 537 |
579 nodeTwo.Update(optionsOld) | 538 nodeTwo.Update(optionsOld) |
580 changes, err := nodeTwo.Write() | 539 changes, err := nodeTwo.Write() |
581 c.Assert(err, IsNil) | 540 c.Assert(err, IsNil) |
582 » c.Assert(changes, Equals, []ItemChange{ | 541 » c.Assert(changes, DeepEquals, []ItemChange{ |
583 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 542 » » {ItemAdded, "alpha", nil, "beta"}, |
584 » » ItemChange{ItemAdded, "one", nil, 1}, | 543 » » {ItemAdded, "one", nil, 1}, |
585 }) | 544 }) |
586 | 545 |
587 // First test node one. | 546 // First test node one. |
588 » c.Assert(nodeOne.Map(), Equals, optionsOld) | 547 » c.Assert(nodeOne.Map(), DeepEquals, optionsOld) |
589 | 548 |
590 // Write on node one. | 549 // Write on node one. |
591 optionsNew := map[string]interface{}{"alpha": "gamma", "one": "two"} | 550 optionsNew := map[string]interface{}{"alpha": "gamma", "one": "two"} |
592 nodeOne.Update(optionsNew) | 551 nodeOne.Update(optionsNew) |
593 changes, err = nodeOne.Write() | 552 changes, err = nodeOne.Write() |
594 c.Assert(err, IsNil) | 553 c.Assert(err, IsNil) |
595 » c.Assert(changes, Equals, []ItemChange{ | 554 » c.Assert(changes, DeepEquals, []ItemChange{ |
596 » » ItemChange{ItemModified, "alpha", "beta", "gamma"}, | 555 » » {ItemModified, "alpha", "beta", "gamma"}, |
597 » » ItemChange{ItemModified, "one", 1, "two"}, | 556 » » {ItemModified, "one", 1, "two"}, |
598 }) | 557 }) |
599 | 558 |
600 // Verify that node one reports as expected. | 559 // Verify that node one reports as expected. |
601 » c.Assert(nodeOne.Map(), Equals, optionsNew) | 560 » c.Assert(nodeOne.Map(), DeepEquals, optionsNew) |
602 | 561 |
603 // Verify that node two has still the old data. | 562 // Verify that node two has still the old data. |
604 » c.Assert(nodeTwo.Map(), Equals, optionsOld) | 563 » c.Assert(nodeTwo.Map(), DeepEquals, optionsOld) |
605 | 564 |
606 // Now issue a Set/Write from node two. This will | 565 // Now issue a Set/Write from node two. This will |
607 // merge the data deleting 'one' and updating | 566 // merge the data deleting 'one' and updating |
608 // other values. | 567 // other values. |
609 optionsMerge := map[string]interface{}{"alpha": "cappa", "new": "next"} | 568 optionsMerge := map[string]interface{}{"alpha": "cappa", "new": "next"} |
610 nodeTwo.Update(optionsMerge) | 569 nodeTwo.Update(optionsMerge) |
611 nodeTwo.Delete("one") | 570 nodeTwo.Delete("one") |
612 | 571 |
613 expected := map[string]interface{}{"alpha": "cappa", "new": "next"} | 572 expected := map[string]interface{}{"alpha": "cappa", "new": "next"} |
614 changes, err = nodeTwo.Write() | 573 changes, err = nodeTwo.Write() |
615 c.Assert(err, IsNil) | 574 c.Assert(err, IsNil) |
616 » c.Assert(changes, Equals, []ItemChange{ | 575 » c.Assert(changes, DeepEquals, []ItemChange{ |
617 » » ItemChange{ItemModified, "alpha", "beta", "cappa"}, | 576 » » {ItemModified, "alpha", "beta", "cappa"}, |
618 » » ItemChange{ItemAdded, "new", nil, "next"}, | 577 » » {ItemAdded, "new", nil, "next"}, |
619 » » ItemChange{ItemDeleted, "one", 1, nil}, | 578 » » {ItemDeleted, "one", 1, nil}, |
620 }) | 579 }) |
621 » c.Assert(expected, Equals, nodeTwo.Map()) | 580 » c.Assert(expected, DeepEquals, nodeTwo.Map()) |
622 | 581 |
623 // But node one still reflects the former data. | 582 // But node one still reflects the former data. |
624 » c.Assert(nodeOne.Map(), Equals, optionsNew) | 583 » c.Assert(nodeOne.Map(), DeepEquals, optionsNew) |
625 } | 584 } |
626 | 585 |
627 func (s ConfigNodeSuite) TestSetItem(c *C) { | 586 func (s ConfigNodeSuite) TestSetItem(c *C) { |
628 // Check that Set works as expected. | 587 // Check that Set works as expected. |
629 node, err := readConfigNode(s.zkConn, s.path) | 588 node, err := readConfigNode(s.zkConn, s.path) |
630 c.Assert(err, IsNil) | 589 c.Assert(err, IsNil) |
631 options := map[string]interface{}{"alpha": "beta", "one": 1} | 590 options := map[string]interface{}{"alpha": "beta", "one": 1} |
632 node.Set("alpha", "beta") | 591 node.Set("alpha", "beta") |
633 node.Set("one", 1) | 592 node.Set("one", 1) |
634 changes, err := node.Write() | 593 changes, err := node.Write() |
635 c.Assert(err, IsNil) | 594 c.Assert(err, IsNil) |
636 » c.Assert(changes, Equals, []ItemChange{ | 595 » c.Assert(changes, DeepEquals, []ItemChange{ |
637 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 596 » » {ItemAdded, "alpha", nil, "beta"}, |
638 » » ItemChange{ItemAdded, "one", nil, 1}, | 597 » » {ItemAdded, "one", nil, 1}, |
639 }) | 598 }) |
640 // Check local state. | 599 // Check local state. |
641 » c.Assert(node.Map(), Equals, options) | 600 » c.Assert(node.Map(), DeepEquals, options) |
642 // Check ZooKeeper state. | 601 // Check ZooKeeper state. |
643 yaml, _, err := s.zkConn.Get(s.path) | 602 yaml, _, err := s.zkConn.Get(s.path) |
644 c.Assert(err, IsNil) | 603 c.Assert(err, IsNil) |
645 zkData := make(map[string]interface{}) | 604 zkData := make(map[string]interface{}) |
646 err = goyaml.Unmarshal([]byte(yaml), zkData) | 605 err = goyaml.Unmarshal([]byte(yaml), zkData) |
647 » c.Assert(zkData, Equals, options) | 606 » c.Assert(zkData, DeepEquals, options) |
648 } | 607 } |
649 | 608 |
650 func (s ConfigNodeSuite) TestMultipleReads(c *C) { | 609 func (s ConfigNodeSuite) TestMultipleReads(c *C) { |
651 // Check that reads without writes always resets the data. | 610 // Check that reads without writes always resets the data. |
652 nodeOne, err := readConfigNode(s.zkConn, s.path) | 611 nodeOne, err := readConfigNode(s.zkConn, s.path) |
653 c.Assert(err, IsNil) | 612 c.Assert(err, IsNil) |
654 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) | 613 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) |
655 value, ok := nodeOne.Get("alpha") | 614 value, ok := nodeOne.Get("alpha") |
656 c.Assert(ok, Equals, true) | 615 c.Assert(ok, Equals, true) |
657 c.Assert(value, Equals, "beta") | 616 c.Assert(value, Equals, "beta") |
658 value, ok = nodeOne.Get("foo") | 617 value, ok = nodeOne.Get("foo") |
659 c.Assert(ok, Equals, true) | 618 c.Assert(ok, Equals, true) |
660 c.Assert(value, Equals, "bar") | 619 c.Assert(value, Equals, "bar") |
661 value, ok = nodeOne.Get("baz") | 620 value, ok = nodeOne.Get("baz") |
662 c.Assert(ok, Equals, false) | 621 c.Assert(ok, Equals, false) |
663 | 622 |
664 // A read resets the data to the empty state. | 623 // A read resets the data to the empty state. |
665 err = nodeOne.Read() | 624 err = nodeOne.Read() |
666 c.Assert(err, IsNil) | 625 c.Assert(err, IsNil) |
667 » c.Assert(nodeOne.Map(), Equals, map[string]interface{}{}) | 626 » c.Assert(nodeOne.Map(), DeepEquals, map[string]interface{}{}) |
668 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) | 627 nodeOne.Update(map[string]interface{}{"alpha": "beta", "foo": "bar"}) |
669 changes, err := nodeOne.Write() | 628 changes, err := nodeOne.Write() |
670 c.Assert(err, IsNil) | 629 c.Assert(err, IsNil) |
671 » c.Assert(changes, Equals, []ItemChange{ | 630 » c.Assert(changes, DeepEquals, []ItemChange{ |
672 » » ItemChange{ItemAdded, "alpha", nil, "beta"}, | 631 » » {ItemAdded, "alpha", nil, "beta"}, |
673 » » ItemChange{ItemAdded, "foo", nil, "bar"}, | 632 » » {ItemAdded, "foo", nil, "bar"}, |
674 }) | 633 }) |
675 | 634 |
676 // A write retains the newly set values. | 635 // A write retains the newly set values. |
677 value, ok = nodeOne.Get("alpha") | 636 value, ok = nodeOne.Get("alpha") |
678 c.Assert(ok, Equals, true) | 637 c.Assert(ok, Equals, true) |
679 c.Assert(value, Equals, "beta") | 638 c.Assert(value, Equals, "beta") |
680 value, ok = nodeOne.Get("foo") | 639 value, ok = nodeOne.Get("foo") |
681 c.Assert(ok, Equals, true) | 640 c.Assert(ok, Equals, true) |
682 c.Assert(value, Equals, "bar") | 641 c.Assert(value, Equals, "bar") |
683 | 642 |
684 // Now get another state instance and change ZooKeeper state. | 643 // Now get another state instance and change ZooKeeper state. |
685 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 644 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
686 c.Assert(err, IsNil) | 645 c.Assert(err, IsNil) |
687 nodeTwo.Update(map[string]interface{}{"foo": "different"}) | 646 nodeTwo.Update(map[string]interface{}{"foo": "different"}) |
688 changes, err = nodeTwo.Write() | 647 changes, err = nodeTwo.Write() |
689 c.Assert(err, IsNil) | 648 c.Assert(err, IsNil) |
690 » c.Assert(changes, Equals, []ItemChange{ | 649 » c.Assert(changes, DeepEquals, []ItemChange{ |
691 » » ItemChange{ItemModified, "foo", "bar", "different"}, | 650 » » {ItemModified, "foo", "bar", "different"}, |
692 }) | 651 }) |
693 | 652 |
694 // This should pull in the new state into node one. | 653 // This should pull in the new state into node one. |
695 err = nodeOne.Read() | 654 err = nodeOne.Read() |
696 c.Assert(err, IsNil) | 655 c.Assert(err, IsNil) |
697 value, ok = nodeOne.Get("alpha") | 656 value, ok = nodeOne.Get("alpha") |
698 c.Assert(ok, Equals, true) | 657 c.Assert(ok, Equals, true) |
699 c.Assert(value, Equals, "beta") | 658 c.Assert(value, Equals, "beta") |
700 value, ok = nodeOne.Get("foo") | 659 value, ok = nodeOne.Get("foo") |
701 c.Assert(ok, Equals, true) | 660 c.Assert(ok, Equals, true) |
702 c.Assert(value, Equals, "different") | 661 c.Assert(value, Equals, "different") |
703 } | 662 } |
704 | 663 |
705 func (s ConfigNodeSuite) TestDeleteEmptiesState(c *C) { | 664 func (s ConfigNodeSuite) TestDeleteEmptiesState(c *C) { |
706 // Check that delete creates an empty state. | 665 // Check that delete creates an empty state. |
707 node, err := readConfigNode(s.zkConn, s.path) | 666 node, err := readConfigNode(s.zkConn, s.path) |
708 c.Assert(err, IsNil) | 667 c.Assert(err, IsNil) |
709 node.Set("a", "foo") | 668 node.Set("a", "foo") |
710 changes, err := node.Write() | 669 changes, err := node.Write() |
711 c.Assert(err, IsNil) | 670 c.Assert(err, IsNil) |
712 » c.Assert(changes, Equals, []ItemChange{ | 671 » c.Assert(changes, DeepEquals, []ItemChange{ |
713 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 672 » » {ItemAdded, "a", nil, "foo"}, |
714 }) | 673 }) |
715 node.Delete("a") | 674 node.Delete("a") |
716 changes, err = node.Write() | 675 changes, err = node.Write() |
717 c.Assert(err, IsNil) | 676 c.Assert(err, IsNil) |
718 » c.Assert(changes, Equals, []ItemChange{ | 677 » c.Assert(changes, DeepEquals, []ItemChange{ |
719 » » ItemChange{ItemDeleted, "a", "foo", nil}, | 678 » » {ItemDeleted, "a", "foo", nil}, |
720 }) | 679 }) |
721 » c.Assert(node.Map(), Equals, map[string]interface{}{}) | 680 » c.Assert(node.Map(), DeepEquals, map[string]interface{}{}) |
722 } | 681 } |
723 | 682 |
724 func (s ConfigNodeSuite) TestReadResync(c *C) { | 683 func (s ConfigNodeSuite) TestReadResync(c *C) { |
725 // Check that read pulls the data into the node. | 684 // Check that read pulls the data into the node. |
726 nodeOne, err := readConfigNode(s.zkConn, s.path) | 685 nodeOne, err := readConfigNode(s.zkConn, s.path) |
727 c.Assert(err, IsNil) | 686 c.Assert(err, IsNil) |
728 nodeOne.Set("a", "foo") | 687 nodeOne.Set("a", "foo") |
729 changes, err := nodeOne.Write() | 688 changes, err := nodeOne.Write() |
730 c.Assert(err, IsNil) | 689 c.Assert(err, IsNil) |
731 » c.Assert(changes, Equals, []ItemChange{ | 690 » c.Assert(changes, DeepEquals, []ItemChange{ |
732 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 691 » » {ItemAdded, "a", nil, "foo"}, |
733 }) | 692 }) |
734 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 693 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
735 c.Assert(err, IsNil) | 694 c.Assert(err, IsNil) |
736 nodeTwo.Delete("a") | 695 nodeTwo.Delete("a") |
737 changes, err = nodeTwo.Write() | 696 changes, err = nodeTwo.Write() |
738 c.Assert(err, IsNil) | 697 c.Assert(err, IsNil) |
739 » c.Assert(changes, Equals, []ItemChange{ | 698 » c.Assert(changes, DeepEquals, []ItemChange{ |
740 » » ItemChange{ItemDeleted, "a", "foo", nil}, | 699 » » {ItemDeleted, "a", "foo", nil}, |
741 }) | 700 }) |
742 nodeTwo.Set("a", "bar") | 701 nodeTwo.Set("a", "bar") |
743 changes, err = nodeTwo.Write() | 702 changes, err = nodeTwo.Write() |
744 c.Assert(err, IsNil) | 703 c.Assert(err, IsNil) |
745 » c.Assert(changes, Equals, []ItemChange{ | 704 » c.Assert(changes, DeepEquals, []ItemChange{ |
746 » » ItemChange{ItemAdded, "a", nil, "bar"}, | 705 » » {ItemAdded, "a", nil, "bar"}, |
747 }) | 706 }) |
748 // Read of node one should pick up the new value. | 707 // Read of node one should pick up the new value. |
749 err = nodeOne.Read() | 708 err = nodeOne.Read() |
750 c.Assert(err, IsNil) | 709 c.Assert(err, IsNil) |
751 value, ok := nodeOne.Get("a") | 710 value, ok := nodeOne.Get("a") |
752 c.Assert(ok, Equals, true) | 711 c.Assert(ok, Equals, true) |
753 c.Assert(value, Equals, "bar") | 712 c.Assert(value, Equals, "bar") |
754 } | 713 } |
755 | 714 |
756 func (s ConfigNodeSuite) TestMultipleWrites(c *C) { | 715 func (s ConfigNodeSuite) TestMultipleWrites(c *C) { |
757 // Check that multiple writes only do the right changes. | 716 // Check that multiple writes only do the right changes. |
758 node, err := readConfigNode(s.zkConn, s.path) | 717 node, err := readConfigNode(s.zkConn, s.path) |
759 c.Assert(err, IsNil) | 718 c.Assert(err, IsNil) |
760 node.Update(map[string]interface{}{"foo": "bar", "this": "that"}) | 719 node.Update(map[string]interface{}{"foo": "bar", "this": "that"}) |
761 changes, err := node.Write() | 720 changes, err := node.Write() |
762 c.Assert(err, IsNil) | 721 c.Assert(err, IsNil) |
763 » c.Assert(changes, Equals, []ItemChange{ | 722 » c.Assert(changes, DeepEquals, []ItemChange{ |
764 » » ItemChange{ItemAdded, "foo", nil, "bar"}, | 723 » » {ItemAdded, "foo", nil, "bar"}, |
765 » » ItemChange{ItemAdded, "this", nil, "that"}, | 724 » » {ItemAdded, "this", nil, "that"}, |
766 }) | 725 }) |
767 node.Delete("this") | 726 node.Delete("this") |
768 node.Set("another", "value") | 727 node.Set("another", "value") |
769 changes, err = node.Write() | 728 changes, err = node.Write() |
770 c.Assert(err, IsNil) | 729 c.Assert(err, IsNil) |
771 » c.Assert(changes, Equals, []ItemChange{ | 730 » c.Assert(changes, DeepEquals, []ItemChange{ |
772 » » ItemChange{ItemAdded, "another", nil, "value"}, | 731 » » {ItemAdded, "another", nil, "value"}, |
773 » » ItemChange{ItemDeleted, "this", "that", nil}, | 732 » » {ItemDeleted, "this", "that", nil}, |
774 }) | 733 }) |
775 | 734 |
776 expected := map[string]interface{}{"foo": "bar", "another": "value"} | 735 expected := map[string]interface{}{"foo": "bar", "another": "value"} |
777 » c.Assert(expected, Equals, node.Map()) | 736 » c.Assert(expected, DeepEquals, node.Map()) |
778 | 737 |
779 changes, err = node.Write() | 738 changes, err = node.Write() |
780 c.Assert(err, IsNil) | 739 c.Assert(err, IsNil) |
781 » c.Assert(changes, Equals, []ItemChange{}) | 740 » c.Assert(changes, DeepEquals, []ItemChange{}) |
782 | 741 |
783 err = node.Read() | 742 err = node.Read() |
784 c.Assert(err, IsNil) | 743 c.Assert(err, IsNil) |
785 » c.Assert(expected, Equals, node.Map()) | 744 » c.Assert(expected, DeepEquals, node.Map()) |
786 | 745 |
787 changes, err = node.Write() | 746 changes, err = node.Write() |
788 c.Assert(err, IsNil) | 747 c.Assert(err, IsNil) |
789 » c.Assert(changes, Equals, []ItemChange{}) | 748 » c.Assert(changes, DeepEquals, []ItemChange{}) |
790 } | 749 } |
791 | 750 |
792 func (s ConfigNodeSuite) TestWriteTwice(c *C) { | 751 func (s ConfigNodeSuite) TestWriteTwice(c *C) { |
793 // Check the correct writing into a node by two config nodes. | 752 // Check the correct writing into a node by two config nodes. |
794 nodeOne, err := readConfigNode(s.zkConn, s.path) | 753 nodeOne, err := readConfigNode(s.zkConn, s.path) |
795 c.Assert(err, IsNil) | 754 c.Assert(err, IsNil) |
796 nodeOne.Set("a", "foo") | 755 nodeOne.Set("a", "foo") |
797 changes, err := nodeOne.Write() | 756 changes, err := nodeOne.Write() |
798 c.Assert(err, IsNil) | 757 c.Assert(err, IsNil) |
799 » c.Assert(changes, Equals, []ItemChange{ | 758 » c.Assert(changes, DeepEquals, []ItemChange{ |
800 » » ItemChange{ItemAdded, "a", nil, "foo"}, | 759 » » {ItemAdded, "a", nil, "foo"}, |
801 }) | 760 }) |
802 | 761 |
803 nodeTwo, err := readConfigNode(s.zkConn, s.path) | 762 nodeTwo, err := readConfigNode(s.zkConn, s.path) |
804 c.Assert(err, IsNil) | 763 c.Assert(err, IsNil) |
805 nodeTwo.Set("a", "bar") | 764 nodeTwo.Set("a", "bar") |
806 changes, err = nodeTwo.Write() | 765 changes, err = nodeTwo.Write() |
807 c.Assert(err, IsNil) | 766 c.Assert(err, IsNil) |
808 » c.Assert(changes, Equals, []ItemChange{ | 767 » c.Assert(changes, DeepEquals, []ItemChange{ |
809 » » ItemChange{ItemModified, "a", "foo", "bar"}, | 768 » » {ItemModified, "a", "foo", "bar"}, |
810 }) | 769 }) |
811 | 770 |
812 // Shouldn't write again. Changes were already | 771 // Shouldn't write again. Changes were already |
813 // flushed and acted upon by other parties. | 772 // flushed and acted upon by other parties. |
814 changes, err = nodeOne.Write() | 773 changes, err = nodeOne.Write() |
815 c.Assert(err, IsNil) | 774 c.Assert(err, IsNil) |
816 » c.Assert(changes, Equals, []ItemChange{}) | 775 » c.Assert(changes, DeepEquals, []ItemChange{}) |
817 | 776 |
818 err = nodeOne.Read() | 777 err = nodeOne.Read() |
819 c.Assert(err, IsNil) | 778 c.Assert(err, IsNil) |
820 » c.Assert(nodeOne, Equals, nodeTwo) | 779 » c.Assert(nodeOne, DeepEquals, nodeTwo) |
821 } | 780 } |
| 781 |
| 782 type QuoteSuite struct{} |
| 783 |
| 784 var _ = Suite(&QuoteSuite{}) |
| 785 |
| 786 func (s QuoteSuite) TestUnmodified(c *C) { |
| 787 // Check that a string containig only valid |
| 788 // chars stays unmodified. |
| 789 in := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-" |
| 790 out := Quote(in) |
| 791 c.Assert(out, Equals, in) |
| 792 } |
| 793 |
| 794 func (s QuoteSuite) TestQuote(c *C) { |
| 795 // Check that invalid chars are translated correctly. |
| 796 in := "hello_there/how'are~you-today.sir" |
| 797 out := Quote(in) |
| 798 c.Assert(out, Equals, "hello_5f_there_2f_how_27_are_7e_you-today.sir") |
| 799 } |
OLD | NEW |