github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/apiserver/machine/machiner_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package machine_test 5 6 import ( 7 "github.com/juju/names" 8 jc "github.com/juju/testing/checkers" 9 gc "gopkg.in/check.v1" 10 11 "github.com/juju/juju/apiserver/common" 12 "github.com/juju/juju/apiserver/machine" 13 "github.com/juju/juju/apiserver/params" 14 apiservertesting "github.com/juju/juju/apiserver/testing" 15 "github.com/juju/juju/network" 16 "github.com/juju/juju/state" 17 "github.com/juju/juju/state/multiwatcher" 18 statetesting "github.com/juju/juju/state/testing" 19 "github.com/juju/juju/status" 20 ) 21 22 type machinerSuite struct { 23 commonSuite 24 25 resources *common.Resources 26 machiner *machine.MachinerAPI 27 } 28 29 var _ = gc.Suite(&machinerSuite{}) 30 31 func (s *machinerSuite) SetUpTest(c *gc.C) { 32 s.commonSuite.SetUpTest(c) 33 34 // Create the resource registry separately to track invocations to 35 // Register. 36 s.resources = common.NewResources() 37 38 // Create a machiner API for machine 1. 39 machiner, err := machine.NewMachinerAPI( 40 s.State, 41 s.resources, 42 s.authorizer, 43 ) 44 c.Assert(err, jc.ErrorIsNil) 45 s.machiner = machiner 46 } 47 48 func (s *machinerSuite) TestMachinerFailsWithNonMachineAgentUser(c *gc.C) { 49 anAuthorizer := s.authorizer 50 anAuthorizer.Tag = names.NewUnitTag("ubuntu/1") 51 aMachiner, err := machine.NewMachinerAPI(s.State, s.resources, anAuthorizer) 52 c.Assert(err, gc.NotNil) 53 c.Assert(aMachiner, gc.IsNil) 54 c.Assert(err, gc.ErrorMatches, "permission denied") 55 } 56 57 func (s *machinerSuite) TestSetStatus(c *gc.C) { 58 err := s.machine0.SetStatus(status.StatusStarted, "blah", nil) 59 c.Assert(err, jc.ErrorIsNil) 60 err = s.machine1.SetStatus(status.StatusStopped, "foo", nil) 61 c.Assert(err, jc.ErrorIsNil) 62 63 args := params.SetStatus{ 64 Entities: []params.EntityStatusArgs{ 65 {Tag: "machine-1", Status: status.StatusError, Info: "not really"}, 66 {Tag: "machine-0", Status: status.StatusStopped, Info: "foobar"}, 67 {Tag: "machine-42", Status: status.StatusStarted, Info: "blah"}, 68 }} 69 result, err := s.machiner.SetStatus(args) 70 c.Assert(err, jc.ErrorIsNil) 71 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 72 Results: []params.ErrorResult{ 73 {nil}, 74 {apiservertesting.ErrUnauthorized}, 75 {apiservertesting.ErrUnauthorized}, 76 }, 77 }) 78 79 // Verify machine 0 - no change. 80 statusInfo, err := s.machine0.Status() 81 c.Assert(err, jc.ErrorIsNil) 82 c.Assert(statusInfo.Status, gc.Equals, status.StatusStarted) 83 c.Assert(statusInfo.Message, gc.Equals, "blah") 84 // ...machine 1 is fine though. 85 statusInfo, err = s.machine1.Status() 86 c.Assert(err, jc.ErrorIsNil) 87 c.Assert(statusInfo.Status, gc.Equals, status.StatusError) 88 c.Assert(statusInfo.Message, gc.Equals, "not really") 89 } 90 91 func (s *machinerSuite) TestLife(c *gc.C) { 92 err := s.machine1.EnsureDead() 93 c.Assert(err, jc.ErrorIsNil) 94 err = s.machine1.Refresh() 95 c.Assert(err, jc.ErrorIsNil) 96 c.Assert(s.machine1.Life(), gc.Equals, state.Dead) 97 98 args := params.Entities{Entities: []params.Entity{ 99 {Tag: "machine-1"}, 100 {Tag: "machine-0"}, 101 {Tag: "machine-42"}, 102 }} 103 result, err := s.machiner.Life(args) 104 c.Assert(err, jc.ErrorIsNil) 105 c.Assert(result, gc.DeepEquals, params.LifeResults{ 106 Results: []params.LifeResult{ 107 {Life: "dead"}, 108 {Error: apiservertesting.ErrUnauthorized}, 109 {Error: apiservertesting.ErrUnauthorized}, 110 }, 111 }) 112 } 113 114 func (s *machinerSuite) TestEnsureDead(c *gc.C) { 115 c.Assert(s.machine0.Life(), gc.Equals, state.Alive) 116 c.Assert(s.machine1.Life(), gc.Equals, state.Alive) 117 118 args := params.Entities{Entities: []params.Entity{ 119 {Tag: "machine-1"}, 120 {Tag: "machine-0"}, 121 {Tag: "machine-42"}, 122 }} 123 result, err := s.machiner.EnsureDead(args) 124 c.Assert(err, jc.ErrorIsNil) 125 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 126 Results: []params.ErrorResult{ 127 {nil}, 128 {apiservertesting.ErrUnauthorized}, 129 {apiservertesting.ErrUnauthorized}, 130 }, 131 }) 132 133 err = s.machine0.Refresh() 134 c.Assert(err, jc.ErrorIsNil) 135 c.Assert(s.machine0.Life(), gc.Equals, state.Alive) 136 err = s.machine1.Refresh() 137 c.Assert(err, jc.ErrorIsNil) 138 c.Assert(s.machine1.Life(), gc.Equals, state.Dead) 139 140 // Try it again on a Dead machine; should work. 141 args = params.Entities{ 142 Entities: []params.Entity{{Tag: "machine-1"}}, 143 } 144 result, err = s.machiner.EnsureDead(args) 145 c.Assert(err, jc.ErrorIsNil) 146 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 147 Results: []params.ErrorResult{{nil}}, 148 }) 149 150 // Verify Life is unchanged. 151 err = s.machine1.Refresh() 152 c.Assert(err, jc.ErrorIsNil) 153 c.Assert(s.machine1.Life(), gc.Equals, state.Dead) 154 } 155 156 func (s *machinerSuite) TestSetMachineAddresses(c *gc.C) { 157 c.Assert(s.machine0.Addresses(), gc.HasLen, 0) 158 c.Assert(s.machine1.Addresses(), gc.HasLen, 0) 159 160 addresses := network.NewAddresses("127.0.0.1", "8.8.8.8") 161 162 args := params.SetMachinesAddresses{MachineAddresses: []params.MachineAddresses{ 163 {Tag: "machine-1", Addresses: params.FromNetworkAddresses(addresses)}, 164 {Tag: "machine-0", Addresses: params.FromNetworkAddresses(addresses)}, 165 {Tag: "machine-42", Addresses: params.FromNetworkAddresses(addresses)}, 166 }} 167 168 result, err := s.machiner.SetMachineAddresses(args) 169 c.Assert(err, jc.ErrorIsNil) 170 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 171 Results: []params.ErrorResult{ 172 {nil}, 173 {apiservertesting.ErrUnauthorized}, 174 {apiservertesting.ErrUnauthorized}, 175 }, 176 }) 177 178 err = s.machine1.Refresh() 179 c.Assert(err, jc.ErrorIsNil) 180 181 expectedAddresses := network.NewAddresses("8.8.8.8", "127.0.0.1") 182 c.Assert(s.machine1.MachineAddresses(), gc.DeepEquals, expectedAddresses) 183 err = s.machine0.Refresh() 184 c.Assert(err, jc.ErrorIsNil) 185 c.Assert(s.machine0.MachineAddresses(), gc.HasLen, 0) 186 } 187 188 func (s *machinerSuite) TestSetEmptyMachineAddresses(c *gc.C) { 189 // Set some addresses so we can ensure they are removed. 190 addresses := network.NewAddresses("127.0.0.1", "8.8.8.8") 191 args := params.SetMachinesAddresses{MachineAddresses: []params.MachineAddresses{ 192 {Tag: "machine-1", Addresses: params.FromNetworkAddresses(addresses)}, 193 }} 194 result, err := s.machiner.SetMachineAddresses(args) 195 c.Assert(err, jc.ErrorIsNil) 196 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 197 Results: []params.ErrorResult{ 198 {nil}, 199 }, 200 }) 201 err = s.machine1.Refresh() 202 c.Assert(err, jc.ErrorIsNil) 203 c.Assert(s.machine1.MachineAddresses(), gc.HasLen, 2) 204 205 args.MachineAddresses[0].Addresses = nil 206 result, err = s.machiner.SetMachineAddresses(args) 207 c.Assert(err, jc.ErrorIsNil) 208 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 209 Results: []params.ErrorResult{ 210 {nil}, 211 }, 212 }) 213 214 err = s.machine1.Refresh() 215 c.Assert(err, jc.ErrorIsNil) 216 c.Assert(s.machine1.MachineAddresses(), gc.HasLen, 0) 217 } 218 219 func (s *machinerSuite) TestJobs(c *gc.C) { 220 args := params.Entities{Entities: []params.Entity{ 221 {Tag: "machine-1"}, 222 {Tag: "machine-0"}, 223 {Tag: "machine-42"}, 224 }} 225 226 result, err := s.machiner.Jobs(args) 227 c.Assert(err, jc.ErrorIsNil) 228 c.Assert(result, gc.DeepEquals, params.JobsResults{ 229 Results: []params.JobsResult{ 230 {Jobs: []multiwatcher.MachineJob{multiwatcher.JobHostUnits}}, 231 {Error: apiservertesting.ErrUnauthorized}, 232 {Error: apiservertesting.ErrUnauthorized}, 233 }, 234 }) 235 } 236 237 func (s *machinerSuite) TestWatch(c *gc.C) { 238 c.Assert(s.resources.Count(), gc.Equals, 0) 239 240 args := params.Entities{Entities: []params.Entity{ 241 {Tag: "machine-1"}, 242 {Tag: "machine-0"}, 243 {Tag: "machine-42"}, 244 }} 245 result, err := s.machiner.Watch(args) 246 c.Assert(err, jc.ErrorIsNil) 247 c.Assert(result, gc.DeepEquals, params.NotifyWatchResults{ 248 Results: []params.NotifyWatchResult{ 249 {NotifyWatcherId: "1"}, 250 {Error: apiservertesting.ErrUnauthorized}, 251 {Error: apiservertesting.ErrUnauthorized}, 252 }, 253 }) 254 255 // Verify the resource was registered and stop when done 256 c.Assert(s.resources.Count(), gc.Equals, 1) 257 c.Assert(result.Results[0].NotifyWatcherId, gc.Equals, "1") 258 resource := s.resources.Get("1") 259 defer statetesting.AssertStop(c, resource) 260 261 // Check that the Watch has consumed the initial event ("returned" in 262 // the Watch call) 263 wc := statetesting.NewNotifyWatcherC(c, s.State, resource.(state.NotifyWatcher)) 264 wc.AssertNoChange() 265 } 266 267 func (s *machinerSuite) TestSetObservedNetworkConfig(c *gc.C) { 268 c.Skip("dimitern: Test disabled until dummy provider is fixed properly") 269 devices, err := s.machine1.AllLinkLayerDevices() 270 c.Assert(err, jc.ErrorIsNil) 271 c.Assert(devices, gc.HasLen, 0) 272 273 err = s.machine1.SetInstanceInfo("i-foo", "FAKE_NONCE", nil, nil, nil, nil, nil) 274 c.Assert(err, jc.ErrorIsNil) 275 276 observedConfig := []params.NetworkConfig{{ 277 InterfaceName: "lo", 278 InterfaceType: "loopback", 279 CIDR: "127.0.0.0/8", 280 Address: "127.0.0.1", 281 }, { 282 InterfaceName: "eth0", 283 InterfaceType: "ethernet", 284 MACAddress: "aa:bb:cc:dd:ee:f0", 285 CIDR: "0.10.0.0/24", 286 Address: "0.10.0.2", 287 }, { 288 InterfaceName: "eth1", 289 InterfaceType: "ethernet", 290 MACAddress: "aa:bb:cc:dd:ee:f1", 291 CIDR: "0.20.0.0/24", 292 Address: "0.20.0.2", 293 }} 294 args := params.SetMachineNetworkConfig{ 295 Tag: s.machine1.Tag().String(), 296 Config: observedConfig, 297 } 298 299 err = s.machiner.SetObservedNetworkConfig(args) 300 c.Assert(err, jc.ErrorIsNil) 301 302 devices, err = s.machine1.AllLinkLayerDevices() 303 c.Assert(err, jc.ErrorIsNil) 304 c.Assert(devices, gc.HasLen, 3) 305 306 for _, device := range devices { 307 c.Check(device.Name(), gc.Matches, `(lo|eth0|eth1)`) 308 c.Check(string(device.Type()), gc.Matches, `(loopback|ethernet)`) 309 c.Check(device.MACAddress(), gc.Matches, `(|aa:bb:cc:dd:ee:f0|aa:bb:cc:dd:ee:f1)`) 310 } 311 } 312 313 func (s *machinerSuite) TestSetObservedNetworkConfigPermissions(c *gc.C) { 314 args := params.SetMachineNetworkConfig{ 315 Tag: "machine-0", 316 Config: nil, 317 } 318 319 err := s.machiner.SetObservedNetworkConfig(args) 320 c.Assert(err, gc.ErrorMatches, "permission denied") 321 } 322 323 func (s *machinerSuite) TestSetProviderNetworkConfig(c *gc.C) { 324 c.Skip("dimitern: Test disabled until dummy provider is fixed properly") 325 devices, err := s.machine1.AllLinkLayerDevices() 326 c.Assert(err, jc.ErrorIsNil) 327 c.Assert(devices, gc.HasLen, 0) 328 329 err = s.machine1.SetInstanceInfo("i-foo", "FAKE_NONCE", nil, nil, nil, nil, nil) 330 c.Assert(err, jc.ErrorIsNil) 331 332 args := params.Entities{Entities: []params.Entity{ 333 {Tag: s.machine1.Tag().String()}, 334 }} 335 336 result, err := s.machiner.SetProviderNetworkConfig(args) 337 c.Assert(err, jc.ErrorIsNil) 338 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 339 Results: []params.ErrorResult{{nil}}, 340 }) 341 342 devices, err = s.machine1.AllLinkLayerDevices() 343 c.Assert(err, jc.ErrorIsNil) 344 c.Assert(devices, gc.HasLen, 3) 345 346 for _, device := range devices { 347 c.Check(device.Name(), gc.Matches, `eth[0-2]`) 348 c.Check(string(device.Type()), gc.Equals, "ethernet") 349 c.Check(device.MACAddress(), gc.Matches, `aa:bb:cc:dd:ee:f[0-2]`) 350 addrs, err := device.Addresses() 351 c.Check(err, jc.ErrorIsNil) 352 c.Check(addrs, gc.HasLen, 1) 353 } 354 } 355 356 func (s *machinerSuite) TestSetProviderNetworkConfigPermissions(c *gc.C) { 357 args := params.Entities{Entities: []params.Entity{ 358 {Tag: "machine-1"}, 359 {Tag: "machine-0"}, 360 {Tag: "machine-42"}, 361 }} 362 363 result, err := s.machiner.SetProviderNetworkConfig(args) 364 c.Assert(err, jc.ErrorIsNil) 365 c.Assert(result, gc.DeepEquals, params.ErrorResults{ 366 Results: []params.ErrorResult{ 367 {Error: apiservertesting.NotProvisionedError(s.machine1.Id())}, 368 {Error: apiservertesting.ErrUnauthorized}, 369 {Error: apiservertesting.ErrUnauthorized}, 370 }, 371 }) 372 }