launchpad.net/~rogpeppe/juju-core/500-errgo-fix@v0.0.0-20140213181702-000000002356/state/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 errgo "launchpad.net/errgo/errors" 8 gc "launchpad.net/gocheck" 9 10 "launchpad.net/juju-core/charm" 11 "launchpad.net/juju-core/errors" 12 "launchpad.net/juju-core/instance" 13 "launchpad.net/juju-core/state" 14 "launchpad.net/juju-core/state/api/params" 15 "launchpad.net/juju-core/state/api/uniter" 16 statetesting "launchpad.net/juju-core/state/testing" 17 jc "launchpad.net/juju-core/testing/checkers" 18 ) 19 20 type unitSuite struct { 21 uniterSuite 22 23 apiUnit *uniter.Unit 24 } 25 26 var _ = gc.Suite(&unitSuite{}) 27 28 func (s *unitSuite) SetUpTest(c *gc.C) { 29 s.uniterSuite.SetUpTest(c) 30 31 var err error 32 s.apiUnit, err = s.uniter.Unit(s.wordpressUnit.Tag()) 33 c.Assert(err, gc.IsNil) 34 } 35 36 func (s *unitSuite) TearDownTest(c *gc.C) { 37 s.uniterSuite.TearDownTest(c) 38 } 39 40 func (s *unitSuite) TestUnitAndUnitTag(c *gc.C) { 41 apiUnitFoo, err := s.uniter.Unit("unit-foo-42") 42 c.Assert(err, gc.ErrorMatches, "permission denied") 43 c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized) 44 c.Assert(apiUnitFoo, gc.IsNil) 45 46 c.Assert(s.apiUnit.Tag(), gc.Equals, "unit-wordpress-0") 47 } 48 49 func (s *unitSuite) TestSetStatus(c *gc.C) { 50 status, info, data, err := s.wordpressUnit.Status() 51 c.Assert(err, gc.IsNil) 52 c.Assert(status, gc.Equals, params.StatusPending) 53 c.Assert(info, gc.Equals, "") 54 c.Assert(data, gc.HasLen, 0) 55 56 err = s.apiUnit.SetStatus(params.StatusStarted, "blah", nil) 57 c.Assert(err, gc.IsNil) 58 59 status, info, data, err = s.wordpressUnit.Status() 60 c.Assert(err, gc.IsNil) 61 c.Assert(status, gc.Equals, params.StatusStarted) 62 c.Assert(info, gc.Equals, "blah") 63 c.Assert(data, gc.HasLen, 0) 64 } 65 66 func (s *unitSuite) TestEnsureDead(c *gc.C) { 67 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 68 69 err := s.apiUnit.EnsureDead() 70 c.Assert(err, gc.IsNil) 71 72 err = s.wordpressUnit.Refresh() 73 c.Assert(err, gc.IsNil) 74 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Dead) 75 76 err = s.apiUnit.EnsureDead() 77 c.Assert(err, gc.IsNil) 78 err = s.wordpressUnit.Refresh() 79 c.Assert(err, gc.IsNil) 80 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Dead) 81 82 err = s.wordpressUnit.Remove() 83 c.Assert(err, gc.IsNil) 84 err = s.wordpressUnit.Refresh() 85 c.Assert(err, jc.Satisfies, errors.IsNotFoundError) 86 87 err = s.apiUnit.EnsureDead() 88 c.Assert(err, gc.ErrorMatches, `unit "wordpress/0" not found`) 89 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 90 } 91 92 func (s *unitSuite) TestDestroy(c *gc.C) { 93 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 94 95 err := s.apiUnit.Destroy() 96 c.Assert(err, gc.IsNil) 97 98 err = s.wordpressUnit.Refresh() 99 c.Assert(err, gc.ErrorMatches, `unit "wordpress/0" not found`) 100 } 101 102 func (s *unitSuite) TestDestroyAllSubordinates(c *gc.C) { 103 c.Assert(s.wordpressUnit.Life(), gc.Equals, state.Alive) 104 105 // Call without subordinates - no change. 106 err := s.apiUnit.DestroyAllSubordinates() 107 c.Assert(err, gc.IsNil) 108 109 // Add a couple of subordinates and try again. 110 _, _, loggingSub := s.addRelatedService(c, "wordpress", "logging", s.wordpressUnit) 111 _, _, monitoringSub := s.addRelatedService(c, "wordpress", "monitoring", s.wordpressUnit) 112 c.Assert(loggingSub.Life(), gc.Equals, state.Alive) 113 c.Assert(monitoringSub.Life(), gc.Equals, state.Alive) 114 115 err = s.apiUnit.DestroyAllSubordinates() 116 c.Assert(err, gc.IsNil) 117 118 // Verify they got destroyed. 119 err = loggingSub.Refresh() 120 c.Assert(err, gc.IsNil) 121 c.Assert(loggingSub.Life(), gc.Equals, state.Dying) 122 err = monitoringSub.Refresh() 123 c.Assert(err, gc.IsNil) 124 c.Assert(monitoringSub.Life(), gc.Equals, state.Dying) 125 } 126 127 func (s *unitSuite) TestRefresh(c *gc.C) { 128 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 129 130 err := s.apiUnit.EnsureDead() 131 c.Assert(err, gc.IsNil) 132 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 133 134 err = s.apiUnit.Refresh() 135 c.Assert(err, gc.IsNil) 136 c.Assert(s.apiUnit.Life(), gc.Equals, params.Dead) 137 } 138 139 func (s *unitSuite) TestWatch(c *gc.C) { 140 c.Assert(s.apiUnit.Life(), gc.Equals, params.Alive) 141 142 w, err := s.apiUnit.Watch() 143 c.Assert(err, gc.IsNil) 144 defer statetesting.AssertStop(c, w) 145 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 146 147 // Initial event. 148 wc.AssertOneChange() 149 150 // Change something other than the lifecycle and make sure it's 151 // not detected. 152 err = s.apiUnit.SetStatus(params.StatusStarted, "not really", nil) 153 c.Assert(err, gc.IsNil) 154 wc.AssertNoChange() 155 156 // Make the unit dead and check it's detected. 157 err = s.apiUnit.EnsureDead() 158 c.Assert(err, gc.IsNil) 159 wc.AssertOneChange() 160 161 statetesting.AssertStop(c, w) 162 wc.AssertClosed() 163 } 164 165 func (s *unitSuite) TestResolve(c *gc.C) { 166 err := s.wordpressUnit.SetResolved(state.ResolvedRetryHooks) 167 c.Assert(err, gc.IsNil) 168 169 mode, err := s.apiUnit.Resolved() 170 c.Assert(err, gc.IsNil) 171 c.Assert(mode, gc.Equals, params.ResolvedRetryHooks) 172 173 err = s.apiUnit.ClearResolved() 174 c.Assert(err, gc.IsNil) 175 176 mode, err = s.apiUnit.Resolved() 177 c.Assert(err, gc.IsNil) 178 c.Assert(mode, gc.Equals, params.ResolvedNone) 179 } 180 181 func (s *unitSuite) TestIsPrincipal(c *gc.C) { 182 ok, err := s.apiUnit.IsPrincipal() 183 c.Assert(err, gc.IsNil) 184 c.Assert(ok, jc.IsTrue) 185 } 186 187 func (s *unitSuite) TestHasSubordinates(c *gc.C) { 188 found, err := s.apiUnit.HasSubordinates() 189 c.Assert(err, gc.IsNil) 190 c.Assert(found, jc.IsFalse) 191 192 // Add a couple of subordinates and try again. 193 s.addRelatedService(c, "wordpress", "logging", s.wordpressUnit) 194 s.addRelatedService(c, "wordpress", "monitoring", s.wordpressUnit) 195 196 found, err = s.apiUnit.HasSubordinates() 197 c.Assert(err, gc.IsNil) 198 c.Assert(found, jc.IsTrue) 199 } 200 201 func (s *unitSuite) TestGetSetPublicAddress(c *gc.C) { 202 address, err := s.apiUnit.PublicAddress() 203 c.Assert(err, gc.ErrorMatches, `"unit-wordpress-0" has no public address set`) 204 205 err = s.apiUnit.SetPublicAddress("1.2.3.4") 206 c.Assert(err, gc.IsNil) 207 208 address, err = s.apiUnit.PublicAddress() 209 c.Assert(err, gc.IsNil) 210 c.Assert(address, gc.Equals, "1.2.3.4") 211 } 212 213 func (s *unitSuite) TestGetSetPrivateAddress(c *gc.C) { 214 address, err := s.apiUnit.PrivateAddress() 215 c.Assert(err, gc.ErrorMatches, `"unit-wordpress-0" has no private address set`) 216 217 err = s.apiUnit.SetPrivateAddress("1.2.3.4") 218 c.Assert(err, gc.IsNil) 219 220 address, err = s.apiUnit.PrivateAddress() 221 c.Assert(err, gc.IsNil) 222 c.Assert(address, gc.Equals, "1.2.3.4") 223 } 224 225 func (s *unitSuite) TestOpenClosePort(c *gc.C) { 226 ports := s.wordpressUnit.OpenedPorts() 227 c.Assert(ports, gc.HasLen, 0) 228 229 err := s.apiUnit.OpenPort("foo", 1234) 230 c.Assert(err, gc.IsNil) 231 err = s.apiUnit.OpenPort("bar", 4321) 232 c.Assert(err, gc.IsNil) 233 234 err = s.wordpressUnit.Refresh() 235 c.Assert(err, gc.IsNil) 236 ports = s.wordpressUnit.OpenedPorts() 237 // OpenedPorts returns a sorted slice. 238 c.Assert(ports, gc.DeepEquals, []instance.Port{ 239 {Protocol: "bar", Number: 4321}, 240 {Protocol: "foo", Number: 1234}, 241 }) 242 243 err = s.apiUnit.ClosePort("bar", 4321) 244 c.Assert(err, gc.IsNil) 245 246 err = s.wordpressUnit.Refresh() 247 c.Assert(err, gc.IsNil) 248 ports = s.wordpressUnit.OpenedPorts() 249 // OpenedPorts returns a sorted slice. 250 c.Assert(ports, gc.DeepEquals, []instance.Port{ 251 {Protocol: "foo", Number: 1234}, 252 }) 253 254 err = s.apiUnit.ClosePort("foo", 1234) 255 c.Assert(err, gc.IsNil) 256 257 err = s.wordpressUnit.Refresh() 258 c.Assert(err, gc.IsNil) 259 ports = s.wordpressUnit.OpenedPorts() 260 c.Assert(ports, gc.HasLen, 0) 261 } 262 263 func (s *unitSuite) TestGetSetCharmURL(c *gc.C) { 264 // No charm URL set yet. 265 curl, ok := s.wordpressUnit.CharmURL() 266 c.Assert(curl, gc.IsNil) 267 c.Assert(ok, jc.IsFalse) 268 269 // Now check the same through the API. 270 _, err := s.apiUnit.CharmURL() 271 c.Assert(errgo.Cause(err), gc.Equals, uniter.ErrNoCharmURLSet) 272 273 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 274 c.Assert(err, gc.IsNil) 275 276 curl, err = s.apiUnit.CharmURL() 277 c.Assert(err, gc.IsNil) 278 c.Assert(curl, gc.NotNil) 279 c.Assert(curl.String(), gc.Equals, s.wordpressCharm.String()) 280 } 281 282 func (s *unitSuite) TestConfigSettings(c *gc.C) { 283 // Make sure ConfigSettings returns an error when 284 // no charm URL is set, as its state counterpart does. 285 settings, err := s.apiUnit.ConfigSettings() 286 c.Assert(err, gc.ErrorMatches, "unit charm not set") 287 288 // Now set the charm and try again. 289 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 290 c.Assert(err, gc.IsNil) 291 292 settings, err = s.apiUnit.ConfigSettings() 293 c.Assert(err, gc.IsNil) 294 c.Assert(settings, gc.DeepEquals, charm.Settings{ 295 "blog-title": "My Title", 296 }) 297 298 // Update the config and check we get the changes on the next call. 299 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 300 "blog-title": "superhero paparazzi", 301 }) 302 c.Assert(err, gc.IsNil) 303 304 settings, err = s.apiUnit.ConfigSettings() 305 c.Assert(err, gc.IsNil) 306 c.Assert(settings, gc.DeepEquals, charm.Settings{ 307 "blog-title": "superhero paparazzi", 308 }) 309 } 310 311 func (s *unitSuite) TestWatchConfigSettings(c *gc.C) { 312 // Make sure WatchConfigSettings returns an error when 313 // no charm URL is set, as its state counterpart does. 314 w, err := s.apiUnit.WatchConfigSettings() 315 c.Assert(err, gc.ErrorMatches, "unit charm not set") 316 317 // Now set the charm and try again. 318 err = s.apiUnit.SetCharmURL(s.wordpressCharm.URL()) 319 c.Assert(err, gc.IsNil) 320 321 w, err = s.apiUnit.WatchConfigSettings() 322 defer statetesting.AssertStop(c, w) 323 wc := statetesting.NewNotifyWatcherC(c, s.BackingState, w) 324 325 // Initial event. 326 wc.AssertOneChange() 327 328 // Update config a couple of times, check a single event. 329 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 330 "blog-title": "superhero paparazzi", 331 }) 332 c.Assert(err, gc.IsNil) 333 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 334 "blog-title": "sauceror central", 335 }) 336 c.Assert(err, gc.IsNil) 337 wc.AssertOneChange() 338 339 // Non-change is not reported. 340 err = s.wordpressService.UpdateConfigSettings(charm.Settings{ 341 "blog-title": "sauceror central", 342 }) 343 c.Assert(err, gc.IsNil) 344 wc.AssertNoChange() 345 346 // NOTE: This test is not as exhaustive as the one in state, 347 // because the watcher is already tested there. Here we just 348 // ensure we get the events when we expect them and don't get 349 // them when they're not expected. 350 351 statetesting.AssertStop(c, w) 352 wc.AssertClosed() 353 } 354 355 func (s *unitSuite) TestServiceNameAndTag(c *gc.C) { 356 c.Assert(s.apiUnit.ServiceName(), gc.Equals, "wordpress") 357 c.Assert(s.apiUnit.ServiceTag(), gc.Equals, "service-wordpress") 358 }