github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/api/uniter/unit_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package uniter_test 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/juju/errors" 11 "github.com/juju/names" 12 jc "github.com/juju/testing/checkers" 13 gc "gopkg.in/check.v1" 14 "gopkg.in/juju/charm.v4" 15 16 "github.com/juju/juju/api/base" 17 "github.com/juju/juju/api/uniter" 18 "github.com/juju/juju/apiserver/params" 19 "github.com/juju/juju/network" 20 "github.com/juju/juju/state" 21 statetesting "github.com/juju/juju/state/testing" 22 ) 23 24 type unitSuite struct { 25 uniterSuite 26 27 apiUnit *uniter.Unit 28 } 29 30 var _ = gc.Suite(&unitSuite{}) 31 32 func (s *unitSuite) SetUpTest(c *gc.C) { 33 s.uniterSuite.SetUpTest(c) 34 35 var err error 36 s.apiUnit, err = s.uniter.Unit(s.wordpressUnit.Tag().(names.UnitTag)) 37 c.Assert(err, jc.ErrorIsNil) 38 } 39 40 func (s *unitSuite) TestRequestReboot(c *gc.C) { 41 err := s.apiUnit.RequestReboot() 42 c.Assert(err, jc.ErrorIsNil) 43 rFlag, err := s.wordpressMachine.GetRebootFlag() 44 c.Assert(err, jc.ErrorIsNil) 45 c.Assert(rFlag, jc.IsTrue) 46 } 47 48 func (s *unitSuite) TestUnitAndUnitTag(c *gc.C) { 49 apiUnitFoo, err := s.uniter.Unit(names.NewUnitTag("foo/42")) 50 c.Assert(err, gc.ErrorMatches, "permission denied") 51 c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized) 52 c.Assert(apiUnitFoo, gc.IsNil) 53 54 c.Assert(s.apiUnit.Tag(), gc.Equals, s.wordpressUnit.Tag().(names.UnitTag)) 55 } 56 57 func (s *unitSuite) TestSetStatus(c *gc.C) { 58 status, info, data, err := s.wordpressUnit.Status() 59 c.Assert(err, jc.ErrorIsNil) 60 c.Assert(status, gc.Equals, state.StatusAllocating) 61 c.Assert(info, gc.Equals, "") 62 c.Assert(data, gc.HasLen, 0) 63 64 err = s.apiUnit.SetStatus(params.StatusActive, "blah", nil) 65 c.Assert(err, jc.ErrorIsNil) 66 67 status, info, data, err = s.wordpressUnit.Status() 68 c.Assert(err, jc.ErrorIsNil) 69 c.Assert(status, gc.Equals, state.StatusActive) 70 c.Assert(info, gc.Equals, "blah") 71 c.Assert(data, gc.HasLen, 0) 72 } 73 74 func (s *unitSuite) TestEnsureDead(c *gc.C) { 75 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 76 77 err := s.apiUnit.EnsureDead() 78 c.Assert(err, jc.ErrorIsNil) 79 80 err = s.wordpressUnit.Refresh() 81 c.Assert(err, jc.ErrorIsNil) 82 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Dead) 83 84 err = s.apiUnit.EnsureDead() 85 c.Assert(err, jc.ErrorIsNil) 86 err = s.wordpressUnit.Refresh() 87 c.Assert(err, jc.ErrorIsNil) 88 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Dead) 89 90 err = s.wordpressUnit.Remove() 91 c.Assert(err, jc.ErrorIsNil) 92 err = s.wordpressUnit.Refresh() 93 c.Assert(err, jc.Satisfies, errors.IsNotFound) 94 95 err = s.apiUnit.EnsureDead() 96 c.Assert(err, gc.ErrorMatches, `unit "wordpress/0" not found`) 97 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 98 } 99 100 func (s *unitSuite) TestDestroy(c *gc.C) { 101 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 102 103 err := s.apiUnit.Destroy() 104 c.Assert(err, jc.ErrorIsNil) 105 106 err = s.wordpressUnit.Refresh() 107 c.Assert(err, gc.ErrorMatches, `unit "wordpress/0" not found`) 108 } 109 110 func (s *unitSuite) TestDestroyAllSubordinates(c *gc.C) { 111 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 112 113 // Call without subordinates - no change. 114 err := s.apiUnit.DestroyAllSubordinates() 115 c.Assert(err, jc.ErrorIsNil) 116 117 // Add a couple of subordinates and try again. 118 _, _, loggingSub := s.addRelatedService(c, "wordpress", "logging", s.wordpressUnit) 119 _, _, monitoringSub := s.addRelatedService(c, "wordpress", "monitoring", s.wordpressUnit) 120 c.Assert(loggingSub.Life(), gc.Equals, state.Alive) 121 c.Assert(monitoringSub.Life(), gc.Equals, state.Alive) 122 123 err = s.apiUnit.DestroyAllSubordinates() 124 c.Assert(err, jc.ErrorIsNil) 125 126 // Verify they got destroyed. 127 err = loggingSub.Refresh() 128 c.Assert(err, jc.ErrorIsNil) 129 c.Assert(loggingSub.Life(), gc.Equals, state.Dying) 130 err = monitoringSub.Refresh() 131 c.Assert(err, jc.ErrorIsNil) 132 c.Assert(monitoringSub.Life(), gc.Equals, state.Dying) 133 } 134 135 func (s *unitSuite) TestRefresh(c *gc.C) { 136 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 137 138 err := s.apiUnit.EnsureDead() 139 c.Assert(err, jc.ErrorIsNil) 140 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 141 142 err = s.apiUnit.Refresh() 143 c.Assert(err, jc.ErrorIsNil) 144 c.Assert(s.apiUnit.Life(), gc.Equals, params.Dead) 145 } 146 147 func (s *unitSuite) TestWatch(c *gc.C) { 148 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 149 150 w, err := s.apiUnit.Watch() 151 c.Assert(err, jc.ErrorIsNil) 152 defer statetesting.AssertStop(c, w) 153 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 154 155 // Initial event. 156 wc.AssertOneChange() 157 158 // Change something other than the lifecycle and make sure it's 159 // not detected. 160 err = s.apiUnit.SetStatus(params.StatusActive, "not really", nil) 161 c.Assert(err, jc.ErrorIsNil) 162 wc.AssertNoChange() 163 164 // Make the unit dead and check it's detected. 165 err = s.apiUnit.EnsureDead() 166 c.Assert(err, jc.ErrorIsNil) 167 wc.AssertOneChange() 168 169 statetesting.AssertStop(c, w) 170 wc.AssertClosed() 171 } 172 173 func (s *unitSuite) TestResolve(c *gc.C) { 174 err := s.wordpressUnit.SetResolved(state.ResolvedRetryHooks) 175 c.Assert(err, jc.ErrorIsNil) 176 177 mode, err := s.apiUnit.Resolved() 178 c.Assert(err, jc.ErrorIsNil) 179 c.Assert(mode, gc.Equals, params.ResolvedRetryHooks) 180 181 err = s.apiUnit.ClearResolved() 182 c.Assert(err, jc.ErrorIsNil) 183 184 mode, err = s.apiUnit.Resolved() 185 c.Assert(err, jc.ErrorIsNil) 186 c.Assert(mode, gc.Equals, params.ResolvedNone) 187 } 188 189 func (s *unitSuite) TestAssignedMachineV0NotImplemented(c *gc.C) { 190 s.patchNewState(c, uniter.NewStateV0) 191 192 _, err := s.apiUnit.AssignedMachine() 193 c.Assert(err, jc.Satisfies, errors.IsNotImplemented) 194 c.Assert(err.Error(), gc.Equals, "unit.AssignedMachine() (need V1+) not implemented") 195 } 196 197 func (s *unitSuite) TestAssignedMachineV1(c *gc.C) { 198 s.patchNewState(c, uniter.NewStateV1) 199 200 machineTag, err := s.apiUnit.AssignedMachine() 201 c.Assert(err, jc.ErrorIsNil) 202 c.Assert(machineTag, gc.Equals, s.wordpressMachine.Tag()) 203 } 204 205 func (s *unitSuite) TestIsPrincipal(c *gc.C) { 206 ok, err := s.apiUnit.IsPrincipal() 207 c.Assert(err, jc.ErrorIsNil) 208 c.Assert(ok, jc.IsTrue) 209 } 210 211 func (s *unitSuite) TestHasSubordinates(c *gc.C) { 212 found, err := s.apiUnit.HasSubordinates() 213 c.Assert(err, jc.ErrorIsNil) 214 c.Assert(found, jc.IsFalse) 215 216 // Add a couple of subordinates and try again. 217 s.addRelatedService(c, "wordpress", "logging", s.wordpressUnit) 218 s.addRelatedService(c, "wordpress", "monitoring", s.wordpressUnit) 219 220 found, err = s.apiUnit.HasSubordinates() 221 c.Assert(err, jc.ErrorIsNil) 222 c.Assert(found, jc.IsTrue) 223 } 224 225 func (s *unitSuite) TestPublicAddress(c *gc.C) { 226 address, err := s.apiUnit.PublicAddress() 227 c.Assert(err, gc.ErrorMatches, `"unit-wordpress-0" has no public address set`) 228 229 err = s.wordpressMachine.SetAddresses(network.NewAddress("1.2.3.4", network.ScopePublic)) 230 c.Assert(err, jc.ErrorIsNil) 231 232 address, err = s.apiUnit.PublicAddress() 233 c.Assert(err, jc.ErrorIsNil) 234 c.Assert(address, gc.Equals, "1.2.3.4") 235 } 236 237 func (s *unitSuite) TestPrivateAddress(c *gc.C) { 238 address, err := s.apiUnit.PrivateAddress() 239 c.Assert(err, gc.ErrorMatches, `"unit-wordpress-0" has no private address set`) 240 241 err = s.wordpressMachine.SetAddresses(network.NewAddress("1.2.3.4", network.ScopeCloudLocal)) 242 c.Assert(err, jc.ErrorIsNil) 243 244 address, err = s.apiUnit.PrivateAddress() 245 c.Assert(err, jc.ErrorIsNil) 246 c.Assert(address, gc.Equals, "1.2.3.4") 247 } 248 249 func (s *unitSuite) TestAvailabilityZone(c *gc.C) { 250 uniter.PatchUnitResponse(s, s.apiUnit, "AvailabilityZone", 251 func(result interface{}) error { 252 if results, ok := result.(*params.StringResults); ok { 253 results.Results = []params.StringResult{{ 254 Result: "a-zone", 255 }} 256 } 257 return nil 258 }, 259 ) 260 261 zone, err := s.apiUnit.AvailabilityZone() 262 c.Assert(err, jc.ErrorIsNil) 263 264 c.Check(zone, gc.Equals, "a-zone") 265 } 266 267 func (s *unitSuite) TestOpenClosePortRanges(c *gc.C) { 268 ports, err := s.wordpressUnit.OpenedPorts() 269 c.Assert(err, jc.ErrorIsNil) 270 c.Assert(ports, gc.HasLen, 0) 271 272 err = s.apiUnit.OpenPorts("tcp", 1234, 1400) 273 c.Assert(err, jc.ErrorIsNil) 274 err = s.apiUnit.OpenPorts("udp", 4321, 5000) 275 c.Assert(err, jc.ErrorIsNil) 276 277 ports, err = s.wordpressUnit.OpenedPorts() 278 c.Assert(err, jc.ErrorIsNil) 279 // OpenedPorts returns a sorted slice. 280 c.Assert(ports, gc.DeepEquals, []network.PortRange{ 281 {Protocol: "tcp", FromPort: 1234, ToPort: 1400}, 282 {Protocol: "udp", FromPort: 4321, ToPort: 5000}, 283 }) 284 285 err = s.apiUnit.ClosePorts("udp", 4321, 5000) 286 c.Assert(err, jc.ErrorIsNil) 287 288 ports, err = s.wordpressUnit.OpenedPorts() 289 c.Assert(err, jc.ErrorIsNil) 290 // OpenedPorts returns a sorted slice. 291 c.Assert(ports, gc.DeepEquals, []network.PortRange{ 292 {Protocol: "tcp", FromPort: 1234, ToPort: 1400}, 293 }) 294 295 err = s.apiUnit.ClosePorts("tcp", 1234, 1400) 296 c.Assert(err, jc.ErrorIsNil) 297 298 ports, err = s.wordpressUnit.OpenedPorts() 299 c.Assert(err, jc.ErrorIsNil) 300 c.Assert(ports, gc.HasLen, 0) 301 } 302 303 func (s *unitSuite) TestOpenClosePort(c *gc.C) { 304 ports, err := s.wordpressUnit.OpenedPorts() 305 c.Assert(err, jc.ErrorIsNil) 306 c.Assert(ports, gc.HasLen, 0) 307 308 err = s.apiUnit.OpenPort("tcp", 1234) 309 c.Assert(err, jc.ErrorIsNil) 310 err = s.apiUnit.OpenPort("tcp", 4321) 311 c.Assert(err, jc.ErrorIsNil) 312 313 ports, err = s.wordpressUnit.OpenedPorts() 314 c.Assert(err, jc.ErrorIsNil) 315 // OpenedPorts returns a sorted slice. 316 c.Assert(ports, gc.DeepEquals, []network.PortRange{ 317 {Protocol: "tcp", FromPort: 1234, ToPort: 1234}, 318 {Protocol: "tcp", FromPort: 4321, ToPort: 4321}, 319 }) 320 321 err = s.apiUnit.ClosePort("tcp", 4321) 322 c.Assert(err, jc.ErrorIsNil) 323 324 ports, err = s.wordpressUnit.OpenedPorts() 325 c.Assert(err, jc.ErrorIsNil) 326 // OpenedPorts returns a sorted slice. 327 c.Assert(ports, gc.DeepEquals, []network.PortRange{ 328 {Protocol: "tcp", FromPort: 1234, ToPort: 1234}, 329 }) 330 331 err = s.apiUnit.ClosePort("tcp", 1234) 332 c.Assert(err, jc.ErrorIsNil) 333 334 ports, err = s.wordpressUnit.OpenedPorts() 335 c.Assert(err, jc.ErrorIsNil) 336 c.Assert(ports, gc.HasLen, 0) 337 } 338 339 func (s *unitSuite) TestGetSetCharmURL(c *gc.C) { 340 // No charm URL set yet. 341 curl, ok := s.wordpressUnit.CharmURL() 342 c.Assert(curl, gc.IsNil) 343 c.Assert(ok, jc.IsFalse) 344 345 // Now check the same through the API. 346 _, err := s.apiUnit.CharmURL() 347 c.Assert(err, gc.Equals, uniter.ErrNoCharmURLSet) 348 349 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 350 c.Assert(err, jc.ErrorIsNil) 351 352 curl, err = s.apiUnit.CharmURL() 353 c.Assert(err, jc.ErrorIsNil) 354 c.Assert(curl, gc.NotNil) 355 c.Assert(curl.String(), gc.Equals, s.wordpressCharm.String()) 356 } 357 358 func (s *unitSuite) TestConfigSettings(c *gc.C) { 359 // Make sure ConfigSettings returns an error when 360 // no charm URL is set, as its state counterpart does. 361 settings, err := s.apiUnit.ConfigSettings() 362 c.Assert(err, gc.ErrorMatches, "unit charm not set") 363 364 // Now set the charm and try again. 365 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 366 c.Assert(err, jc.ErrorIsNil) 367 368 settings, err = s.apiUnit.ConfigSettings() 369 c.Assert(err, jc.ErrorIsNil) 370 c.Assert(settings, gc.DeepEquals, charm.Settings{ 371 "blog-title": "My Title", 372 }) 373 374 // Update the config and check we get the changes on the next call. 375 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 376 "blog-title": "superhero paparazzi", 377 }) 378 c.Assert(err, jc.ErrorIsNil) 379 380 settings, err = s.apiUnit.ConfigSettings() 381 c.Assert(err, jc.ErrorIsNil) 382 c.Assert(settings, gc.DeepEquals, charm.Settings{ 383 "blog-title": "superhero paparazzi", 384 }) 385 } 386 387 func (s *unitSuite) TestWatchConfigSettings(c *gc.C) { 388 // Make sure WatchConfigSettings returns an error when 389 // no charm URL is set, as its state counterpart does. 390 w, err := s.apiUnit.WatchConfigSettings() 391 c.Assert(err, gc.ErrorMatches, "unit charm not set") 392 393 // Now set the charm and try again. 394 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 395 c.Assert(err, jc.ErrorIsNil) 396 397 w, err = s.apiUnit.WatchConfigSettings() 398 defer statetesting.AssertStop(c, w) 399 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 400 401 // Initial event. 402 wc.AssertOneChange() 403 404 // Update config a couple of times, check a single event. 405 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 406 "blog-title": "superhero paparazzi", 407 }) 408 c.Assert(err, jc.ErrorIsNil) 409 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 410 "blog-title": "sauceror central", 411 }) 412 c.Assert(err, jc.ErrorIsNil) 413 wc.AssertOneChange() 414 415 // Non-change is not reported. 416 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 417 "blog-title": "sauceror central", 418 }) 419 c.Assert(err, jc.ErrorIsNil) 420 wc.AssertNoChange() 421 422 // NOTE: This test is not as exhaustive as the one in state, 423 // because the watcher is already tested there. Here we just 424 // ensure we get the events when we expect them and don't get 425 // them when they're not expected. 426 427 statetesting.AssertStop(c, w) 428 wc.AssertClosed() 429 } 430 431 func (s *unitSuite) TestWatchActionNotifications(c *gc.C) { 432 w, err := s.apiUnit.WatchActionNotifications() 433 c.Assert(err, jc.ErrorIsNil) 434 435 defer statetesting.AssertStop(c, w) 436 wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) 437 438 // Initial event. 439 wc.AssertChange() 440 441 // Add a couple of actions and make sure the changes are detected. 442 action, err := s.wordpressUnit.AddAction("fakeaction", map[string]interface{}{ 443 "outfile": "foo.txt", 444 }) 445 c.Assert(err, jc.ErrorIsNil) 446 wc.AssertChange(action.Id()) 447 448 action, err = s.wordpressUnit.AddAction("fakeaction", map[string]interface{}{ 449 "outfile": "foo.bz2", 450 "compression": map[string]interface{}{ 451 "kind": "bzip", 452 "quality": float64(5.0), 453 }, 454 }) 455 c.Assert(err, jc.ErrorIsNil) 456 wc.AssertChange(action.Id()) 457 458 statetesting.AssertStop(c, w) 459 wc.AssertClosed() 460 } 461 462 func (s *unitSuite) TestWatchActionNotificationsError(c *gc.C) { 463 uniter.PatchUnitResponse(s, s.apiUnit, "WatchActionNotifications", 464 func(result interface{}) error { 465 return fmt.Errorf("Test error") 466 }, 467 ) 468 469 _, err := s.apiUnit.WatchActionNotifications() 470 c.Assert(err.Error(), gc.Equals, "Test error") 471 } 472 473 func (s *unitSuite) TestWatchActionNotificationsErrorResults(c *gc.C) { 474 uniter.PatchUnitResponse(s, s.apiUnit, "WatchActionNotifications", 475 func(results interface{}) error { 476 if results, ok := results.(*params.StringsWatchResults); ok { 477 results.Results = make([]params.StringsWatchResult, 1) 478 results.Results[0] = params.StringsWatchResult{ 479 Error: ¶ms.Error{ 480 Message: "An error in the watch result.", 481 Code: params.CodeNotAssigned, 482 }, 483 } 484 } 485 return nil 486 }, 487 ) 488 489 _, err := s.apiUnit.WatchActionNotifications() 490 c.Assert(err.Error(), gc.Equals, "An error in the watch result.") 491 } 492 493 func (s *unitSuite) TestWatchActionNotificationsNoResults(c *gc.C) { 494 uniter.PatchUnitResponse(s, s.apiUnit, "WatchActionNotifications", 495 func(results interface{}) error { 496 return nil 497 }, 498 ) 499 500 _, err := s.apiUnit.WatchActionNotifications() 501 c.Assert(err.Error(), gc.Equals, "expected 1 result, got 0") 502 } 503 504 func (s *unitSuite) TestWatchActionNotificationsMoreResults(c *gc.C) { 505 uniter.PatchUnitResponse(s, s.apiUnit, "WatchActionNotifications", 506 func(results interface{}) error { 507 if results, ok := results.(*params.StringsWatchResults); ok { 508 results.Results = make([]params.StringsWatchResult, 2) 509 } 510 return nil 511 }, 512 ) 513 514 _, err := s.apiUnit.WatchActionNotifications() 515 c.Assert(err.Error(), gc.Equals, "expected 1 result, got 2") 516 } 517 518 func (s *unitSuite) TestServiceNameAndTag(c *gc.C) { 519 c.Assert(s.apiUnit.ServiceName(), gc.Equals, s.wordpressService.Name()) 520 c.Assert(s.apiUnit.ServiceTag(), gc.Equals, s.wordpressService.Tag()) 521 } 522 523 func (s *unitSuite) TestJoinedRelations(c *gc.C) { 524 joinedRelations, err := s.apiUnit.JoinedRelations() 525 c.Assert(err, jc.ErrorIsNil) 526 c.Assert(joinedRelations, gc.HasLen, 0) 527 528 rel1, _, _ := s.addRelatedService(c, "wordpress", "monitoring", s.wordpressUnit) 529 joinedRelations, err = s.apiUnit.JoinedRelations() 530 c.Assert(err, jc.ErrorIsNil) 531 c.Assert(joinedRelations, gc.DeepEquals, []names.RelationTag{ 532 rel1.Tag().(names.RelationTag), 533 }) 534 535 rel2, _, _ := s.addRelatedService(c, "wordpress", "logging", s.wordpressUnit) 536 joinedRelations, err = s.apiUnit.JoinedRelations() 537 c.Assert(err, jc.ErrorIsNil) 538 c.Assert(joinedRelations, jc.SameContents, []names.RelationTag{ 539 rel1.Tag().(names.RelationTag), 540 rel2.Tag().(names.RelationTag), 541 }) 542 } 543 544 func (s *unitSuite) TestWatchAddresses(c *gc.C) { 545 w, err := s.apiUnit.WatchAddresses() 546 defer statetesting.AssertStop(c, w) 547 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 548 549 // Initial event. 550 wc.AssertOneChange() 551 552 // Update config a couple of times, check a single event. 553 err = s.wordpressMachine.SetAddresses(network.NewAddress("0.1.2.3", network.ScopeUnknown)) 554 c.Assert(err, jc.ErrorIsNil) 555 err = s.wordpressMachine.SetAddresses(network.NewAddress("0.1.2.4", network.ScopeUnknown)) 556 c.Assert(err, jc.ErrorIsNil) 557 wc.AssertOneChange() 558 559 // Non-change is not reported. 560 err = s.wordpressMachine.SetAddresses(network.NewAddress("0.1.2.4", network.ScopeUnknown)) 561 c.Assert(err, jc.ErrorIsNil) 562 wc.AssertNoChange() 563 564 // NOTE: This test is not as exhaustive as the one in state, 565 // because the watcher is already tested there. Here we just 566 // ensure we get the events when we expect them and don't get 567 // them when they're not expected. 568 569 statetesting.AssertStop(c, w) 570 wc.AssertClosed() 571 } 572 573 func (s *unitSuite) TestWatchAddressesErrors(c *gc.C) { 574 err := s.wordpressUnit.UnassignFromMachine() 575 c.Assert(err, jc.ErrorIsNil) 576 _, err = s.apiUnit.WatchAddresses() 577 c.Assert(err, jc.Satisfies, params.IsCodeNotAssigned) 578 } 579 580 func (s *unitSuite) TestAddMetrics(c *gc.C) { 581 uniter.PatchUnitResponse(s, s.apiUnit, "AddMetrics", 582 func(results interface{}) error { 583 result := results.(*params.ErrorResults) 584 result.Results = make([]params.ErrorResult, 1) 585 return nil 586 }, 587 ) 588 metrics := []params.Metric{{"A", "23", time.Now()}, {"B", "27.0", time.Now()}} 589 err := s.apiUnit.AddMetrics(metrics) 590 c.Assert(err, jc.ErrorIsNil) 591 } 592 593 func (s *unitSuite) TestAddMetricsError(c *gc.C) { 594 uniter.PatchUnitResponse(s, s.apiUnit, "AddMetrics", 595 func(results interface{}) error { 596 result := results.(*params.ErrorResults) 597 result.Results = make([]params.ErrorResult, 1) 598 return fmt.Errorf("test error") 599 }, 600 ) 601 metrics := []params.Metric{{"A", "23", time.Now()}, {"B", "27.0", time.Now()}} 602 err := s.apiUnit.AddMetrics(metrics) 603 c.Assert(err, gc.ErrorMatches, "unable to add metric: test error") 604 } 605 606 func (s *unitSuite) TestAddMetricsResultError(c *gc.C) { 607 uniter.PatchUnitResponse(s, s.apiUnit, "AddMetrics", 608 func(results interface{}) error { 609 result := results.(*params.ErrorResults) 610 result.Results = make([]params.ErrorResult, 1) 611 result.Results[0].Error = ¶ms.Error{ 612 Message: "error adding metrics", 613 Code: params.CodeNotAssigned, 614 } 615 return nil 616 }, 617 ) 618 metrics := []params.Metric{{"A", "23", time.Now()}, {"B", "27.0", time.Now()}} 619 err := s.apiUnit.AddMetrics(metrics) 620 c.Assert(err, gc.ErrorMatches, "error adding metrics") 621 } 622 623 func (s *unitSuite) TestMeterStatus(c *gc.C) { 624 uniter.PatchUnitResponse(s, s.apiUnit, "GetMeterStatus", 625 func(results interface{}) error { 626 result := results.(*params.MeterStatusResults) 627 result.Results = make([]params.MeterStatusResult, 1) 628 result.Results[0].Code = "GREEN" 629 result.Results[0].Info = "All ok." 630 return nil 631 }, 632 ) 633 statusCode, statusInfo, err := s.apiUnit.MeterStatus() 634 c.Assert(err, jc.ErrorIsNil) 635 c.Assert(statusCode, gc.Equals, "GREEN") 636 c.Assert(statusInfo, gc.Equals, "All ok.") 637 } 638 639 func (s *unitSuite) TestMeterStatusError(c *gc.C) { 640 uniter.PatchUnitResponse(s, s.apiUnit, "GetMeterStatus", 641 func(results interface{}) error { 642 result := results.(*params.MeterStatusResults) 643 result.Results = make([]params.MeterStatusResult, 1) 644 return fmt.Errorf("boo") 645 }, 646 ) 647 statusCode, statusInfo, err := s.apiUnit.MeterStatus() 648 c.Assert(err, gc.ErrorMatches, "boo") 649 c.Assert(statusCode, gc.Equals, "") 650 c.Assert(statusInfo, gc.Equals, "") 651 } 652 653 func (s *unitSuite) TestMeterStatusResultError(c *gc.C) { 654 uniter.PatchUnitResponse(s, s.apiUnit, "GetMeterStatus", 655 func(results interface{}) error { 656 result := results.(*params.MeterStatusResults) 657 result.Results = make([]params.MeterStatusResult, 1) 658 result.Results[0].Error = ¶ms.Error{ 659 Message: "error getting meter status", 660 Code: params.CodeNotAssigned, 661 } 662 return nil 663 }, 664 ) 665 statusCode, statusInfo, err := s.apiUnit.MeterStatus() 666 c.Assert(err, gc.ErrorMatches, "error getting meter status") 667 c.Assert(statusCode, gc.Equals, "") 668 c.Assert(statusInfo, gc.Equals, "") 669 } 670 671 func (s *unitSuite) TestWatchMeterStatus(c *gc.C) { 672 w, err := s.apiUnit.WatchMeterStatus() 673 defer statetesting.AssertStop(c, w) 674 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 675 676 // Initial event. 677 wc.AssertOneChange() 678 679 err = s.wordpressUnit.SetMeterStatus("GREEN", "ok") 680 c.Assert(err, jc.ErrorIsNil) 681 err = s.wordpressUnit.SetMeterStatus("AMBER", "ok") 682 c.Assert(err, jc.ErrorIsNil) 683 wc.AssertOneChange() 684 685 // Non-change is not reported. 686 err = s.wordpressUnit.SetMeterStatus("AMBER", "ok") 687 c.Assert(err, jc.ErrorIsNil) 688 wc.AssertNoChange() 689 690 statetesting.AssertStop(c, w) 691 wc.AssertClosed() 692 } 693 694 func (s *unitSuite) patchNewState( 695 c *gc.C, 696 patchFunc func(_ base.APICaller, _ names.UnitTag) *uniter.State, 697 ) { 698 s.uniterSuite.patchNewState(c, patchFunc) 699 var err error 700 s.apiUnit, err = s.uniter.Unit(s.wordpressUnit.Tag().(names.UnitTag)) 701 c.Assert(err, jc.ErrorIsNil) 702 }