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