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

Delta Between Two Patch Sets: state/state_test.go

Issue 5727045: Continuation of the unit state implementation. (Closed)
Left Patch Set: Created 12 years ago
Right Patch Set: Continuation of the unit state implementation. 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/state.go ('k') | state/unit.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_test
5
6 import (
7 "fmt"
8 . "launchpad.net/gocheck"
9 "launchpad.net/gozk/zookeeper"
10 "launchpad.net/juju/go/charm"
11 "launchpad.net/juju/go/state"
12 "net/url"
13 "path/filepath"
14 "testing"
15 )
16
17 // TestPackage integrates the tests into gotest.
18 func TestPackage(t *testing.T) {
19 srv, dir := state.ZkSetUpEnvironment(t)
20 defer state.ZkTearDownEnvironment(t, srv, dir)
21
22 TestingT(t)
23 }
24
25 // charmDir returns a directory containing the given test charm.
26 func charmDir(name string) string {
27 return filepath.Join("..", "charm", "testrepo", "series", name)
28 }
29
30 // readCharm returns a test charm by its name.
31 func readCharm(c *C, name string) charm.Charm {
32 ch, err := charm.ReadDir(charmDir(name))
33 c.Assert(err, IsNil)
34 return ch
35 }
36
37 // localCharmURL returns the local URL of a charm.
38 func localCharmURL(ch charm.Charm) *charm.URL {
39 url := fmt.Sprintf("local:series/%s-%d", ch.Meta().Name, ch.Revision())
40 return charm.MustParseURL(url)
41 }
42
43 // addDummyCharm adds the 'dummy' charm state to st.
44 func addDummyCharm(c *C, st *state.State) (*state.Charm, *charm.URL) {
45 ch := readCharm(c, "dummy")
46 curl := localCharmURL(ch)
47 bundleURL, err := url.Parse("http://bundle.url")
48 c.Assert(err, IsNil)
49 dummy, err := st.AddCharm(ch, curl, bundleURL)
50 c.Assert(err, IsNil)
51 return dummy, curl
52 }
53
54 type StateSuite struct {
55 zkServer *zookeeper.Server
56 zkTestRoot string
57 zkTestPort int
58 zkAddr string
59 zkConn *zookeeper.Conn
60 st *state.State
61 }
62
63 var _ = Suite(&StateSuite{})
64
65 func (s *StateSuite) SetUpTest(c *C) {
66 var err error
67 s.st, err = state.Open(&state.Info{
68 Addrs: []string{state.ZkAddr},
69 })
70 c.Assert(err, IsNil)
71 err = s.st.Initialize()
72 c.Assert(err, IsNil)
73 s.zkConn = state.ZkConn(s.st)
74 }
75
76 func (s *StateSuite) TearDownTest(c *C) {
77 // Delete possible nodes, ignore errors.
78 zkRemoveTree(s.zkConn, "/topology")
79 zkRemoveTree(s.zkConn, "/charms")
80 zkRemoveTree(s.zkConn, "/services")
81 zkRemoveTree(s.zkConn, "/machines")
82 zkRemoveTree(s.zkConn, "/units")
83 zkRemoveTree(s.zkConn, "/relations")
84 zkRemoveTree(s.zkConn, "/initialized")
85 s.zkConn.Close()
86 }
87
88 func (s StateSuite) TestAddCharm(c *C) {
89 // Check that adding charms works correctly.
90 dummyCharm := readCharm(c, "dummy")
91 curl := localCharmURL(dummyCharm)
92 bundleURL, err := url.Parse("http://bundle.url")
93 c.Assert(err, IsNil)
94 dummy, err := s.st.AddCharm(dummyCharm, curl, bundleURL)
95 c.Assert(err, IsNil)
96 c.Assert(dummy.URL().String(), Equals, curl.String())
97 _, _, err = s.zkConn.Children("/charms")
98 c.Assert(err, IsNil)
99 }
100
101 func (s StateSuite) TestCharmAttributes(c *C) {
102 // Check that the basic (invariant) fields of the charm
103 // are correctly in place.
104 _, curl := addDummyCharm(c, s.st)
105
106 dummy, err := s.st.Charm(curl)
107 c.Assert(err, IsNil)
108 c.Assert(dummy.URL().String(), Equals, curl.String())
109 c.Assert(dummy.Revision(), Equals, 1)
110 bundleURL, err := url.Parse("http://bundle.url")
111 c.Assert(err, IsNil)
112 c.Assert(dummy.BundleURL(), DeepEquals, bundleURL)
113 meta := dummy.Meta()
114 c.Assert(meta.Name, Equals, "dummy")
115 config := dummy.Config()
116 c.Assert(config.Options["title"], Equals,
117 charm.Option{
118 Default: "My Title",
119 Description: "A descriptive title used for the service." ,
120 Type: "string",
121 },
122 )
123 }
124
125 func (s StateSuite) TestNonExistentCharmPriorToInitialization(c *C) {
126 // Check that getting a charm before any other charm has been added fail s nicely.
127 curl, err := charm.ParseURL("local:series/dummy-1")
128 c.Assert(err, IsNil)
129 _, err = s.st.Charm(curl)
130 c.Assert(err, ErrorMatches, `charm not found: "local:series/dummy-1"`)
131 }
132
133 func (s StateSuite) TestGetNonExistentCharm(c *C) {
134 // Check that getting a non-existent charm fails nicely.
135 addDummyCharm(c, s.st)
136
137 curl := charm.MustParseURL("local:anotherseries/dummy-1")
138 _, err := s.st.Charm(curl)
139 c.Assert(err, ErrorMatches, `charm not found: "local:anotherseries/dummy -1"`)
140 }
141
142 func (s StateSuite) TestAddService(c *C) {
143 // Check that adding services works correctly.
144 dummy, curl := addDummyCharm(c, s.st)
145 wordpress, err := s.st.AddService("wordpress", dummy)
146 c.Assert(err, IsNil)
147 c.Assert(wordpress.Name(), Equals, "wordpress")
148 mysql, err := s.st.AddService("mysql", dummy)
149 c.Assert(err, IsNil)
150 c.Assert(mysql.Name(), Equals, "mysql")
151
152 // Check that retrieving the new created services works correctly.
153 wordpress, err = s.st.Service("wordpress")
154 c.Assert(err, IsNil)
155 c.Assert(wordpress.Name(), Equals, "wordpress")
156 url, err := wordpress.CharmURL()
157 c.Assert(err, IsNil)
158 c.Assert(url.String(), Equals, curl.String())
159 mysql, err = s.st.Service("mysql")
160 c.Assert(err, IsNil)
161 c.Assert(mysql.Name(), Equals, "mysql")
162 url, err = mysql.CharmURL()
163 c.Assert(err, IsNil)
164 c.Assert(url.String(), Equals, curl.String())
165 }
166
167 func (s StateSuite) TestRemoveService(c *C) {
168 dummy, _ := addDummyCharm(c, s.st)
169 service, err := s.st.AddService("wordpress", dummy)
170 c.Assert(err, IsNil)
171
172 // Check that removing the service works correctly.
173 err = s.st.RemoveService(service)
174 c.Assert(err, IsNil)
175 service, err = s.st.Service("wordpress")
176 c.Assert(err, ErrorMatches, `service with name "wordpress" not found`)
177 }
178
179 func (s StateSuite) TestReadNonExistentService(c *C) {
180 _, err := s.st.Service("pressword")
181 c.Assert(err, ErrorMatches, `service with name "pressword" not found`)
182 }
183
184 func (s StateSuite) TestAllServices(c *C) {
185 // Check without existing services.
186 services, err := s.st.AllServices()
187 c.Assert(err, IsNil)
188 c.Assert(len(services), Equals, 0)
189
190 // Check that after adding services the result is ok.
191 dummy, _ := addDummyCharm(c, s.st)
192 _, err = s.st.AddService("wordpress", dummy)
193 c.Assert(err, IsNil)
194 services, err = s.st.AllServices()
195 c.Assert(err, IsNil)
196 c.Assert(len(services), Equals, 1)
197
198 _, err = s.st.AddService("mysql", dummy)
199 c.Assert(err, IsNil)
200 services, err = s.st.AllServices()
201 c.Assert(err, IsNil)
202 c.Assert(len(services), Equals, 2)
203
204 // Check the returned service, order is defined by sorted keys.
205 c.Assert(services[0].Name(), Equals, "wordpress")
206 c.Assert(services[1].Name(), Equals, "mysql")
207 }
208
209 func (s StateSuite) TestServiceCharm(c *C) {
210 dummy, curl := addDummyCharm(c, s.st)
211 wordpress, err := s.st.AddService("wordpress", dummy)
212 c.Assert(err, IsNil)
213
214 // Check that getting and setting the service charm URL works correctly.
215 testcurl, err := wordpress.CharmURL()
216 c.Assert(err, IsNil)
217 c.Assert(testcurl.String(), Equals, curl.String())
218 testcurl, err = charm.ParseURL("local:myseries/mydummy-1")
219 c.Assert(err, IsNil)
220 err = wordpress.SetCharmURL(testcurl)
221 c.Assert(err, IsNil)
222 testcurl, err = wordpress.CharmURL()
223 c.Assert(err, IsNil)
224 c.Assert(testcurl.String(), Equals, "local:myseries/mydummy-1")
225 }
226
227 func (s StateSuite) TestServiceExposed(c *C) {
228 dummy, _ := addDummyCharm(c, s.st)
229 wordpress, err := s.st.AddService("wordpress", dummy)
230 c.Assert(err, IsNil)
231
232 // Check that querying for the exposed flag works correctly.
233 exposed, err := wordpress.IsExposed()
234 c.Assert(err, IsNil)
235 c.Assert(exposed, Equals, false)
236
237 // Check that setting and clearing the exposed flag works correctly.
238 err = wordpress.SetExposed()
239 c.Assert(err, IsNil)
240 exposed, err = wordpress.IsExposed()
241 c.Assert(err, IsNil)
242 c.Assert(exposed, Equals, true)
243 err = wordpress.ClearExposed()
244 c.Assert(err, IsNil)
245 exposed, err = wordpress.IsExposed()
246 c.Assert(err, IsNil)
247 c.Assert(exposed, Equals, false)
248
249 // Check that setting and clearing the exposed flag multiple doesn't fai l.
250 err = wordpress.SetExposed()
251 c.Assert(err, IsNil)
252 err = wordpress.SetExposed()
253 c.Assert(err, IsNil)
254 err = wordpress.ClearExposed()
255 c.Assert(err, IsNil)
256 err = wordpress.ClearExposed()
257 c.Assert(err, IsNil)
258
259 // Check that setting and clearing the exposed flag on removed services also doesn't fail.
260 err = s.st.RemoveService(wordpress)
261 c.Assert(err, IsNil)
262 err = wordpress.ClearExposed()
263 c.Assert(err, IsNil)
264 }
265
266 func (s StateSuite) TestAddUnit(c *C) {
267 dummy, _ := addDummyCharm(c, s.st)
268 wordpress, err := s.st.AddService("wordpress", dummy)
269 c.Assert(err, IsNil)
270
271 // Check that adding units works.
272 unitZero, err := wordpress.AddUnit()
273 c.Assert(err, IsNil)
274 c.Assert(unitZero.Name(), Equals, "wordpress/0")
275 unitOne, err := wordpress.AddUnit()
276 c.Assert(err, IsNil)
277 c.Assert(unitOne.Name(), Equals, "wordpress/1")
278 }
279
280 func (s StateSuite) TestReadUnit(c *C) {
281 dummy, _ := addDummyCharm(c, s.st)
282 wordpress, err := s.st.AddService("wordpress", dummy)
283 c.Assert(err, IsNil)
284 _, err = wordpress.AddUnit()
285 c.Assert(err, IsNil)
286 _, err = wordpress.AddUnit()
287 c.Assert(err, IsNil)
288 mysql, err := s.st.AddService("mysql", dummy)
289 c.Assert(err, IsNil)
290 _, err = mysql.AddUnit()
291 c.Assert(err, IsNil)
292
293 // Check that retrieving a unit works correctly.
294 unit, err := wordpress.Unit("wordpress/0")
295 c.Assert(err, IsNil)
296 c.Assert(unit.Name(), Equals, "wordpress/0")
297
298 // Check that retrieving a non-existent or an invalidly
299 // named unit fail nicely.
300 unit, err = wordpress.Unit("wordpress")
301 c.Assert(err, ErrorMatches, `"wordpress" is not a valid unit name`)
302 unit, err = wordpress.Unit("wordpress/0/0")
303 c.Assert(err, ErrorMatches, `"wordpress/0/0" is not a valid unit name`)
304 unit, err = wordpress.Unit("pressword/0")
305 c.Assert(err, ErrorMatches, `can't find unit "pressword/0" on service "w ordpress"`)
306 unit, err = wordpress.Unit("mysql/0")
307 c.Assert(err, ErrorMatches, `can't find unit "mysql/0" on service "wordp ress"`)
308
309 // Check that retrieving unit names works.
310 unitNames, err := wordpress.UnitNames()
311 c.Assert(err, IsNil)
312 c.Assert(unitNames, DeepEquals, []string{"wordpress/0", "wordpress/1"})
313
314 // Check that retrieving all units works.
315 units, err := wordpress.AllUnits()
316 c.Assert(err, IsNil)
317 c.Assert(len(units), Equals, 2)
318 c.Assert(units[0].Name(), Equals, "wordpress/0")
319 c.Assert(units[1].Name(), Equals, "wordpress/1")
320 }
321
322 func (s StateSuite) TestReadUnitWithChangingState(c *C) {
323 dummy, _ := addDummyCharm(c, s.st)
324 wordpress, err := s.st.AddService("wordpress", dummy)
325 c.Assert(err, IsNil)
326
327 // Check that reading a unit after removing the service
328 // fails nicely.
329 err = s.st.RemoveService(wordpress)
330 c.Assert(err, IsNil)
331 _, err = s.st.Unit("wordpress/0")
332 c.Assert(err, ErrorMatches, `service with name "wordpress" not found`)
333 }
334
335 func (s StateSuite) TestRemoveUnit(c *C) {
336 dummy, _ := addDummyCharm(c, s.st)
337 wordpress, err := s.st.AddService("wordpress", dummy)
338 c.Assert(err, IsNil)
339 _, err = wordpress.AddUnit()
340 c.Assert(err, IsNil)
341 _, err = wordpress.AddUnit()
342 c.Assert(err, IsNil)
343
344 // Check that removing a unit works.
345 unit, err := wordpress.Unit("wordpress/0")
346 c.Assert(err, IsNil)
347 err = wordpress.RemoveUnit(unit)
348 c.Assert(err, IsNil)
349 unitNames, err := wordpress.UnitNames()
350 c.Assert(err, IsNil)
351 c.Assert(unitNames, DeepEquals, []string{"wordpress/1"})
352
353 // Check that removing a non-existent unit fails nicely.
354 err = wordpress.RemoveUnit(unit)
355 c.Assert(err, ErrorMatches, "environment state has changed")
356 }
357
358 func (s StateSuite) TestGetSetPublicAddress(c *C) {
359 dummy, _ := addDummyCharm(c, s.st)
360 wordpress, err := s.st.AddService("wordpress", dummy)
361 c.Assert(err, IsNil)
362 unit, err := wordpress.AddUnit()
363 c.Assert(err, IsNil)
364
365 // Check that retrieving and setting of a public address works.
366 address, err := unit.PublicAddress()
367 c.Assert(err, ErrorMatches, "unit has no public address")
368 err = unit.SetPublicAddress("example.foobar.com")
369 c.Assert(err, IsNil)
370 address, err = unit.PublicAddress()
371 c.Assert(err, IsNil)
372 c.Assert(address, Equals, "example.foobar.com")
373 }
374
375 func (s StateSuite) TestGetSetPrivateAddress(c *C) {
376 dummy, _ := addDummyCharm(c, s.st)
377 wordpress, err := s.st.AddService("wordpress", dummy)
378 c.Assert(err, IsNil)
379 unit, err := wordpress.AddUnit()
380 c.Assert(err, IsNil)
381
382 // Check that retrieving and setting of a private address works.
383 address, err := unit.PrivateAddress()
384 c.Assert(err, ErrorMatches, "unit has no private address")
385 err = unit.SetPrivateAddress("example.local")
386 c.Assert(err, IsNil)
387 address, err = unit.PrivateAddress()
388 c.Assert(err, IsNil)
389 c.Assert(address, Equals, "example.local")
390 }
391
392 func (s StateSuite) TestUnitCharm(c *C) {
393 dummy, curl := addDummyCharm(c, s.st)
394 wordpress, err := s.st.AddService("wordpress", dummy)
395 c.Assert(err, IsNil)
396 unit, err := wordpress.AddUnit()
397 c.Assert(err, IsNil)
398
399 // Check that getting and setting the unit charm URL works correctly.
400 testcurl, err := unit.CharmURL()
401 c.Assert(err, IsNil)
402 c.Assert(testcurl.String(), Equals, curl.String())
403 testcurl, err = charm.ParseURL("local:myseries/mydummy-1")
404 c.Assert(err, IsNil)
405 err = unit.SetCharmURL(testcurl)
406 c.Assert(err, IsNil)
407 testcurl, err = unit.CharmURL()
408 c.Assert(err, IsNil)
409 c.Assert(testcurl.String(), Equals, "local:myseries/mydummy-1")
410 }
411
412 func (s StateSuite) TestUnassignUnitFromMachineWithoutBeingAssigned(c *C) {
413 // When unassigning a machine from a unit, it is possible that
414 // the machine has not been previously assigned, or that it
415 // was assigned but the state changed beneath us. In either
416 // case, the end state is the intended state, so we simply
417 // move forward without any errors here, to avoid having to
418 // handle the extra complexity of dealing with the concurrency
419 // problems.
420 dummy, _ := addDummyCharm(c, s.st)
421 wordpress, err := s.st.AddService("wordpress", dummy)
422 c.Assert(err, IsNil)
423 unit, err := wordpress.AddUnit()
424 c.Assert(err, IsNil)
425
426 err = unit.UnassignFromMachine()
427 c.Assert(err, IsNil)
428
429 // Check that the unit has no machine assigned.
430 wordpress, err = s.st.Service("wordpress")
431 c.Assert(err, IsNil)
432 units, err := wordpress.AllUnits()
433 c.Assert(err, IsNil)
434 unit = units[0]
435 _, err = unit.AssignedMachineId()
436 c.Assert(err, ErrorMatches, `unit not assigned to machine`)
437 }
438
439 func (s StateSuite) TestAssignUnitToMachineAgainFails(c *C) {
440 // Check that assigning an already assigned unit to
441 // a machine fails if it isn't precisely the same
442 // machine.·
443 dummy, _ := addDummyCharm(c, s.st)
444 wordpress, err := s.st.AddService("wordpress", dummy)
445 c.Assert(err, IsNil)
446 unit, err := wordpress.AddUnit()
447 c.Assert(err, IsNil)
448 machineOne, err := s.st.AddMachine()
449 c.Assert(err, IsNil)
450 machineTwo, err := s.st.AddMachine()
451 c.Assert(err, IsNil)
452
453 err = unit.AssignToMachine(machineOne)
454 c.Assert(err, IsNil)
455
456 // Assigning the unit to the same machine should return no error.
457 err = unit.AssignToMachine(machineOne)
458 c.Assert(err, IsNil)
459
460 // Assigning the unit to a different machine should fail.
461 err = unit.AssignToMachine(machineTwo)
462 c.Assert(err, ErrorMatches, `unit "wordpress/0" already assigned to mach ine 0`)
463
464 machineId, err := unit.AssignedMachineId()
465 c.Assert(err, IsNil)
466 c.Assert(machineId, Equals, 0)
467 }
468
469 func (s StateSuite) TestUnassignUnitFromMachineWithChangingState(c *C) {
470 // Check that unassigning while the state changes fails nicely.
471 dummy, _ := addDummyCharm(c, s.st)
472 wordpress, err := s.st.AddService("wordpress", dummy)
473 c.Assert(err, IsNil)
474 unit, err := wordpress.AddUnit()
475 c.Assert(err, IsNil)
476
477 // Remove the unit for the tests.
478 wordpress, err = s.st.Service("wordpress")
479 c.Assert(err, IsNil)
480 units, err := wordpress.AllUnits()
481 c.Assert(err, IsNil)
482 unit = units[0]
483 err = wordpress.RemoveUnit(unit)
484 c.Assert(err, IsNil)
485
486 err = unit.UnassignFromMachine()
487 c.Assert(err, ErrorMatches, "environment state has changed")
488 _, err = unit.AssignedMachineId()
489 c.Assert(err, ErrorMatches, "environment state has changed")
490
491 err = s.st.RemoveService(wordpress)
492 c.Assert(err, IsNil)
493
494 err = unit.UnassignFromMachine()
495 c.Assert(err, ErrorMatches, "environment state has changed")
496 _, err = unit.AssignedMachineId()
497 c.Assert(err, ErrorMatches, "environment state has changed")
498 }
499
500 func (s StateSuite) TestAssignUnitToUnusedMachine(c *C) {
501 // Create root machine that shouldn't be useds.
502 _, err := s.st.AddMachine()
503 c.Assert(err, IsNil)
504 // Check that a unit can be assigned to an unused machine.
505 dummy, _ := addDummyCharm(c, s.st)
506 mysqlService, err := s.st.AddService("mysql", dummy)
507 c.Assert(err, IsNil)
508 mysqlUnit, err := mysqlService.AddUnit()
509 c.Assert(err, IsNil)
510 mysqlMachine, err := s.st.AddMachine()
511 c.Assert(err, IsNil)
512 err = mysqlUnit.AssignToMachine(mysqlMachine)
513 c.Assert(err, IsNil)
514 err = s.st.RemoveService(mysqlService)
515 c.Assert(err, IsNil)
516
517 wordpressService, err := s.st.AddService("wordpress", dummy)
518 c.Assert(err, IsNil)
519 wordpressUnit, err := wordpressService.AddUnit()
520 c.Assert(err, IsNil)
521 wordpressMachine, err := wordpressUnit.AssignToUnusedMachine()
522 c.Assert(err, IsNil)
523
524 c.Assert(wordpressMachine.Id(), Equals, mysqlMachine.Id())
525 }
526
527 func (s StateSuite) TestAssignUnitToUnusedMachineWithChangingService(c *C) {
528 // Create root machine that shouldn't be useds.
529 _, err := s.st.AddMachine()
530 c.Assert(err, IsNil)
531 // Check for a 'state changed' error if a service is manipulated
532 // during reuse.
533 dummy, _ := addDummyCharm(c, s.st)
534 mysqlService, err := s.st.AddService("mysql", dummy)
535 c.Assert(err, IsNil)
536 mysqlUnit, err := mysqlService.AddUnit()
537 c.Assert(err, IsNil)
538 mysqlMachine, err := s.st.AddMachine()
539 c.Assert(err, IsNil)
540 err = mysqlUnit.AssignToMachine(mysqlMachine)
541 c.Assert(err, IsNil)
542 err = s.st.RemoveService(mysqlService)
543 c.Assert(err, IsNil)
544
545 wordpressService, err := s.st.AddService("wordpress", dummy)
546 c.Assert(err, IsNil)
547 wordpressUnit, err := wordpressService.AddUnit()
548 c.Assert(err, IsNil)
549 err = s.st.RemoveService(wordpressService)
550 c.Assert(err, IsNil)
551
552 _, err = wordpressUnit.AssignToUnusedMachine()
553 c.Assert(err, ErrorMatches, "environment state has changed")
554 }
555
556 func (s StateSuite) TestAssignUnitToUnusedMachineWithChangingUnit(c *C) {
557 // Create root machine that shouldn't be useds.
558 _, err := s.st.AddMachine()
559 c.Assert(err, IsNil)
560 // Check for a 'state changed' error if a unit is manipulated
561 // during reuse.
562 dummy, _ := addDummyCharm(c, s.st)
563 mysqlService, err := s.st.AddService("mysql", dummy)
564 c.Assert(err, IsNil)
565 mysqlUnit, err := mysqlService.AddUnit()
566 c.Assert(err, IsNil)
567 mysqlMachine, err := s.st.AddMachine()
568 c.Assert(err, IsNil)
569 err = mysqlUnit.AssignToMachine(mysqlMachine)
570 c.Assert(err, IsNil)
571 err = s.st.RemoveService(mysqlService)
572 c.Assert(err, IsNil)
573
574 wordpressService, err := s.st.AddService("wordpress", dummy)
575 c.Assert(err, IsNil)
576 wordpressUnit, err := wordpressService.AddUnit()
577 c.Assert(err, IsNil)
578 err = wordpressService.RemoveUnit(wordpressUnit)
579 c.Assert(err, IsNil)
580
581 _, err = wordpressUnit.AssignToUnusedMachine()
582 c.Assert(err, ErrorMatches, "environment state has changed")
583 }
584
585 func (s StateSuite) TestAssignUnitToUnusedMachineOnlyZero(c *C) {
586 // Create root machine that shouldn't be useds.
587 _, err := s.st.AddMachine()
588 c.Assert(err, IsNil)
589 // Check that the unit can't be assigned to machine zero.
590 dummy, _ := addDummyCharm(c, s.st)
591 wordpressService, err := s.st.AddService("wordpress", dummy)
592 c.Assert(err, IsNil)
593 wordpressUnit, err := wordpressService.AddUnit()
594 c.Assert(err, IsNil)
595
596 _, err = wordpressUnit.AssignToUnusedMachine()
597 c.Assert(err, ErrorMatches, "no unused machine found") 1 c.Assert(err, ErrorMatches, "no unused machine found")
598 }
599
600 func (s StateSuite) TestAssignUnitToUnusedMachineNoneAvailable(c *C) {
601 // Create machine 0, that shouldn't be used.
602 _, err := s.st.AddMachine()
603 c.Assert(err, IsNil)
604 // Check that assigning without unused machine fails.···
605 dummy, _ := addDummyCharm(c, s.st)
606 mysqlService, err := s.st.AddService("mysql", dummy)
607 c.Assert(err, IsNil)
608 mysqlUnit, err := mysqlService.AddUnit()
609 c.Assert(err, IsNil)
610 mysqlMachine, err := s.st.AddMachine()
611 c.Assert(err, IsNil)
612 err = mysqlUnit.AssignToMachine(mysqlMachine)
613 c.Assert(err, IsNil)
614
615 wordpressService, err := s.st.AddService("wordpress", dummy)
616 c.Assert(err, IsNil)
617 wordpressUnit, err := wordpressService.AddUnit()
618 c.Assert(err, IsNil)
619
620 _, err = wordpressUnit.AssignToUnusedMachine()
621 c.Assert(err, ErrorMatches, "no unused machine found")
622 }
623
624 func (s StateSuite) TestGetSetClearUnitUpgrate(c *C) {
625 // Check that setting and clearing an upgrade flag on a unit works.
626 dummy, _ := addDummyCharm(c, s.st)
627 wordpress, err := s.st.AddService("wordpress", dummy)
628 c.Assert(err, IsNil)
629 unit, err := wordpress.AddUnit()
630 c.Assert(err, IsNil)
631
632 // Defaults to false.
633 upgrade, err := unit.Upgrade()
634 c.Assert(err, IsNil)
635 c.Assert(upgrade, Equals, false)
636
637 // Can be set.
638 err = unit.SetUpgrade()
639 c.Assert(err, IsNil)
640 upgrade, err = unit.Upgrade()
641 c.Assert(err, IsNil)
642 c.Assert(upgrade, Equals, true)
643
644 // Can be set multiple times.
645 err = unit.SetUpgrade()
646 c.Assert(err, IsNil)
647 upgrade, err = unit.Upgrade()
648 c.Assert(err, IsNil)
649 c.Assert(upgrade, Equals, true)
650
651 // Can be cleared.
652 err = unit.ClearUpgrade()
653 c.Assert(err, IsNil)
654 upgrade, err = unit.Upgrade()
655 c.Assert(err, IsNil)
656 c.Assert(upgrade, Equals, false)
657
658 // Can be cleared multiple times
659 err = unit.ClearUpgrade()
660 c.Assert(err, IsNil)
661 upgrade, err = unit.Upgrade()
662 c.Assert(err, IsNil)
663 c.Assert(upgrade, Equals, false)
664 }
665
666 func (s StateSuite) TestGetSetClearResolved(c *C) {
667 // Check that setting and clearing the resolved setting on a unit works.
668 dummy, _ := addDummyCharm(c, s.st)
669 wordpress, err := s.st.AddService("wordpress", dummy)
670 c.Assert(err, IsNil)
671 unit, err := wordpress.AddUnit()
672 c.Assert(err, IsNil)
673
674 setting, err := unit.Resolved()
675 c.Assert(err, IsNil)
676 c.Assert(setting, IsNil)
677
678 err = unit.SetResolved(state.ResolvedNoHooks)
679 c.Assert(err, IsNil)
680 err = unit.SetResolved(state.ResolvedNoHooks)
681 c.Assert(err, ErrorMatches, `unit "wordpress/0" resolved already enabled `)
682 setting, err = unit.Resolved()
683 c.Assert(err, IsNil)
684 c.Assert(setting, DeepEquals, map[string]interface{}{"retry": state.Reso lvedNoHooks})
685
686 err = unit.ClearResolved()
687 c.Assert(err, IsNil)
688 setting, err = unit.Resolved()
689 c.Assert(err, IsNil)
690 c.Assert(setting, IsNil)
691 err = unit.ClearResolved()
692 c.Assert(err, IsNil)
693
694 err = unit.SetResolved(-1)
695 c.Assert(err, ErrorMatches, `invalid retry value: -1`)
696 }
697
698 func (s StateSuite) TestGetOpenPorts(c *C) {
699 // Check that changes to the open ports of units work porperly.
700 dummy, _ := addDummyCharm(c, s.st)
701 wordpress, err := s.st.AddService("wordpress", dummy)
702 c.Assert(err, IsNil)
703 unit, err := wordpress.AddUnit()
704 c.Assert(err, IsNil)
705
706 // Verify no open ports before activity.
707 open, err := unit.OpenPorts()
708 c.Assert(err, IsNil)
709 c.Assert(open, HasLen, 0)
710
711 // Now open and close port.
712 err = unit.OpenPort(80, "tcp")
713 c.Assert(err, IsNil)
714 open, err = unit.OpenPorts()
715 c.Assert(err, IsNil)
716 c.Assert(open, DeepEquals, []state.PortProto{
717 {80, "tcp"},
718 })
719
720 err = unit.OpenPort(53, "udp")
721 c.Assert(err, IsNil)
722 open, err = unit.OpenPorts()
723 c.Assert(err, IsNil)
724 c.Assert(open, DeepEquals, []state.PortProto{
725 {80, "tcp"},
726 {53, "udp"},
727 })
728
729 err = unit.OpenPort(53, "tcp")
730 c.Assert(err, IsNil)
731 open, err = unit.OpenPorts()
732 c.Assert(err, IsNil)
733 c.Assert(open, DeepEquals, []state.PortProto{
734 {80, "tcp"},
735 {53, "udp"},
736 {53, "tcp"},
737 })
738
739 err = unit.OpenPort(443, "tcp")
740 c.Assert(err, IsNil)
741 open, err = unit.OpenPorts()
742 c.Assert(err, IsNil)
743 c.Assert(open, DeepEquals, []state.PortProto{
744 {80, "tcp"},
745 {53, "udp"},
746 {53, "tcp"},
747 {443, "tcp"},
748 })
749
750 err = unit.ClosePort(80, "tcp")
751 c.Assert(err, IsNil)
752 open, err = unit.OpenPorts()
753 c.Assert(err, IsNil)
754 c.Assert(open, DeepEquals, []state.PortProto{
755 {53, "udp"},
756 {53, "tcp"},
757 {443, "tcp"},
758 })
759 } 2 }
760 3
761 // zkRemoveTree recursively removes a tree. 4 // zkRemoveTree recursively removes a tree.
762 func zkRemoveTree(zk *zookeeper.Conn, path string) error { 5 func zkRemoveTree(zk *zookeeper.Conn, path string) error {
763 // First recursively delete the children. 6 // First recursively delete the children.
764 children, _, err := zk.Children(path)
765 if err != nil {
766 return err
767 }
768 for _, child := range children {
769 if err = zkRemoveTree(zk, fmt.Sprintf("%s/%s", path, child)); er r != nil {
770 return err
771 }
772 }
773 // Now delete the path itself.
774 return zk.Delete(path, -1)
775 }
LEFTRIGHT

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