github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/state/api/provisioner/provisioner_test.go (about) 1 // Copyright 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package provisioner_test 5 6 import ( 7 stdtesting "testing" 8 9 "github.com/juju/errors" 10 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 "github.com/juju/utils" 13 gc "launchpad.net/gocheck" 14 15 "github.com/juju/juju/constraints" 16 "github.com/juju/juju/container" 17 "github.com/juju/juju/instance" 18 "github.com/juju/juju/juju/testing" 19 "github.com/juju/juju/state" 20 "github.com/juju/juju/state/api" 21 "github.com/juju/juju/state/api/params" 22 "github.com/juju/juju/state/api/provisioner" 23 apitesting "github.com/juju/juju/state/api/testing" 24 statetesting "github.com/juju/juju/state/testing" 25 coretesting "github.com/juju/juju/testing" 26 "github.com/juju/juju/tools" 27 "github.com/juju/juju/version" 28 ) 29 30 func TestAll(t *stdtesting.T) { 31 coretesting.MgoTestPackage(t) 32 } 33 34 type provisionerSuite struct { 35 testing.JujuConnSuite 36 *apitesting.EnvironWatcherTests 37 *apitesting.APIAddresserTests 38 39 st *api.State 40 machine *state.Machine 41 42 provisioner *provisioner.State 43 } 44 45 var _ = gc.Suite(&provisionerSuite{}) 46 47 func (s *provisionerSuite) SetUpTest(c *gc.C) { 48 s.JujuConnSuite.SetUpTest(c) 49 50 var err error 51 s.machine, err = s.State.AddMachine("quantal", state.JobManageEnviron) 52 c.Assert(err, gc.IsNil) 53 password, err := utils.RandomPassword() 54 c.Assert(err, gc.IsNil) 55 err = s.machine.SetPassword(password) 56 c.Assert(err, gc.IsNil) 57 err = s.machine.SetInstanceInfo("i-manager", "fake_nonce", nil, nil, nil) 58 c.Assert(err, gc.IsNil) 59 s.st = s.OpenAPIAsMachine(c, s.machine.Tag(), password, "fake_nonce") 60 c.Assert(s.st, gc.NotNil) 61 err = s.machine.SetAddresses(instance.NewAddress("0.1.2.3", instance.NetworkUnknown)) 62 c.Assert(err, gc.IsNil) 63 64 // Create the provisioner API facade. 65 s.provisioner = s.st.Provisioner() 66 c.Assert(s.provisioner, gc.NotNil) 67 68 s.EnvironWatcherTests = apitesting.NewEnvironWatcherTests(s.provisioner, s.BackingState, apitesting.HasSecrets) 69 s.APIAddresserTests = apitesting.NewAPIAddresserTests(s.provisioner, s.BackingState) 70 } 71 72 func (s *provisionerSuite) TestMachineTagAndId(c *gc.C) { 73 apiMachine, err := s.provisioner.Machine("machine-42") 74 c.Assert(err, gc.ErrorMatches, "machine 42 not found") 75 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 76 c.Assert(apiMachine, gc.IsNil) 77 78 apiMachine, err = s.provisioner.Machine(s.machine.Tag()) 79 c.Assert(err, gc.IsNil) 80 c.Assert(apiMachine.Tag(), gc.Equals, s.machine.Tag()) 81 c.Assert(apiMachine.Id(), gc.Equals, s.machine.Id()) 82 } 83 84 func (s *provisionerSuite) TestGetSetStatus(c *gc.C) { 85 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 86 c.Assert(err, gc.IsNil) 87 88 status, info, err := apiMachine.Status() 89 c.Assert(err, gc.IsNil) 90 c.Assert(status, gc.Equals, params.StatusPending) 91 c.Assert(info, gc.Equals, "") 92 93 err = apiMachine.SetStatus(params.StatusStarted, "blah", nil) 94 c.Assert(err, gc.IsNil) 95 96 status, info, err = apiMachine.Status() 97 c.Assert(err, gc.IsNil) 98 c.Assert(status, gc.Equals, params.StatusStarted) 99 c.Assert(info, gc.Equals, "blah") 100 _, _, data, err := s.machine.Status() 101 c.Assert(err, gc.IsNil) 102 c.Assert(data, gc.HasLen, 0) 103 } 104 105 func (s *provisionerSuite) TestGetSetStatusWithData(c *gc.C) { 106 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 107 c.Assert(err, gc.IsNil) 108 109 err = apiMachine.SetStatus(params.StatusError, "blah", params.StatusData{"foo": "bar"}) 110 c.Assert(err, gc.IsNil) 111 112 status, info, err := apiMachine.Status() 113 c.Assert(err, gc.IsNil) 114 c.Assert(status, gc.Equals, params.StatusError) 115 c.Assert(info, gc.Equals, "blah") 116 _, _, data, err := s.machine.Status() 117 c.Assert(err, gc.IsNil) 118 c.Assert(data, gc.DeepEquals, params.StatusData{"foo": "bar"}) 119 } 120 121 func (s *provisionerSuite) TestMachinesWithTransientErrors(c *gc.C) { 122 machine, err := s.State.AddMachine("quantal", state.JobHostUnits) 123 c.Assert(err, gc.IsNil) 124 err = machine.SetStatus(params.StatusError, "blah", params.StatusData{"transient": true}) 125 c.Assert(err, gc.IsNil) 126 machines, info, err := s.provisioner.MachinesWithTransientErrors() 127 c.Assert(err, gc.IsNil) 128 c.Assert(machines, gc.HasLen, 1) 129 c.Assert(machines[0].Id(), gc.Equals, "1") 130 c.Assert(info, gc.HasLen, 1) 131 c.Assert(info[0], gc.DeepEquals, params.StatusResult{ 132 Id: "1", 133 Life: "alive", 134 Status: "error", 135 Info: "blah", 136 Data: params.StatusData{"transient": true}, 137 }) 138 } 139 140 func (s *provisionerSuite) TestEnsureDeadAndRemove(c *gc.C) { 141 // Create a fresh machine to test the complete scenario. 142 otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 143 c.Assert(err, gc.IsNil) 144 c.Assert(otherMachine.Life(), gc.Equals, state.Alive) 145 146 apiMachine, err := s.provisioner.Machine(otherMachine.Tag()) 147 c.Assert(err, gc.IsNil) 148 149 err = apiMachine.Remove() 150 c.Assert(err, gc.ErrorMatches, `cannot remove entity "machine-1": still alive`) 151 err = apiMachine.EnsureDead() 152 c.Assert(err, gc.IsNil) 153 154 err = otherMachine.Refresh() 155 c.Assert(err, gc.IsNil) 156 c.Assert(otherMachine.Life(), gc.Equals, state.Dead) 157 158 err = apiMachine.EnsureDead() 159 c.Assert(err, gc.IsNil) 160 err = otherMachine.Refresh() 161 c.Assert(err, gc.IsNil) 162 c.Assert(otherMachine.Life(), gc.Equals, state.Dead) 163 164 err = apiMachine.Remove() 165 c.Assert(err, gc.IsNil) 166 err = otherMachine.Refresh() 167 c.Assert(err, jc.Satisfies, errors.IsNotFound) 168 169 err = apiMachine.EnsureDead() 170 c.Assert(err, gc.ErrorMatches, "machine 1 not found") 171 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 172 173 // Now try to EnsureDead machine 0 - should fail. 174 apiMachine, err = s.provisioner.Machine(s.machine.Tag()) 175 c.Assert(err, gc.IsNil) 176 err = apiMachine.EnsureDead() 177 c.Assert(err, gc.ErrorMatches, "machine 0 is required by the environment") 178 } 179 180 func (s *provisionerSuite) TestRefreshAndLife(c *gc.C) { 181 // Create a fresh machine to test the complete scenario. 182 otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 183 c.Assert(err, gc.IsNil) 184 c.Assert(otherMachine.Life(), gc.Equals, state.Alive) 185 186 apiMachine, err := s.provisioner.Machine(otherMachine.Tag()) 187 c.Assert(err, gc.IsNil) 188 c.Assert(apiMachine.Life(), gc.Equals, params.Alive) 189 190 err = apiMachine.EnsureDead() 191 c.Assert(err, gc.IsNil) 192 c.Assert(apiMachine.Life(), gc.Equals, params.Alive) 193 194 err = apiMachine.Refresh() 195 c.Assert(err, gc.IsNil) 196 c.Assert(apiMachine.Life(), gc.Equals, params.Dead) 197 } 198 199 func (s *provisionerSuite) TestSetInstanceInfo(c *gc.C) { 200 // Create a fresh machine, since machine 0 is already provisioned. 201 notProvisionedMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 202 c.Assert(err, gc.IsNil) 203 204 apiMachine, err := s.provisioner.Machine(notProvisionedMachine.Tag()) 205 c.Assert(err, gc.IsNil) 206 207 instanceId, err := apiMachine.InstanceId() 208 c.Assert(err, jc.Satisfies, params.IsCodeNotProvisioned) 209 c.Assert(err, gc.ErrorMatches, "machine 1 is not provisioned") 210 c.Assert(instanceId, gc.Equals, instance.Id("")) 211 212 hwChars := instance.MustParseHardware("cpu-cores=123", "mem=4G") 213 214 _, err = s.State.Network("net1") 215 c.Assert(err, jc.Satisfies, errors.IsNotFound) 216 _, err = s.State.Network("vlan42") 217 c.Assert(err, jc.Satisfies, errors.IsNotFound) 218 219 ifacesMachine, err := notProvisionedMachine.NetworkInterfaces() 220 c.Assert(err, gc.IsNil) 221 c.Assert(ifacesMachine, gc.HasLen, 0) 222 223 networks := []params.Network{{ 224 Tag: "network-net1", 225 ProviderId: "net1", 226 CIDR: "0.1.2.0/24", 227 VLANTag: 0, 228 }, { 229 Tag: "network-vlan42", 230 ProviderId: "vlan42", 231 CIDR: "0.2.2.0/24", 232 VLANTag: 42, 233 }, { 234 Tag: "network-vlan69", 235 ProviderId: "vlan69", 236 CIDR: "0.3.2.0/24", 237 VLANTag: 69, 238 }, { 239 Tag: "network-vlan42", // duplicated; ignored 240 ProviderId: "vlan42", 241 CIDR: "0.2.2.0/24", 242 VLANTag: 42, 243 }} 244 ifaces := []params.NetworkInterface{{ 245 MACAddress: "aa:bb:cc:dd:ee:f0", 246 NetworkTag: "network-net1", 247 InterfaceName: "eth0", 248 IsVirtual: false, 249 }, { 250 MACAddress: "aa:bb:cc:dd:ee:f1", 251 NetworkTag: "network-net1", 252 InterfaceName: "eth1", 253 IsVirtual: false, 254 }, { 255 MACAddress: "aa:bb:cc:dd:ee:f1", 256 NetworkTag: "network-vlan42", 257 InterfaceName: "eth1.42", 258 IsVirtual: true, 259 }, { 260 MACAddress: "aa:bb:cc:dd:ee:f1", 261 NetworkTag: "network-vlan69", 262 InterfaceName: "eth1.69", 263 IsVirtual: true, 264 }, { 265 MACAddress: "aa:bb:cc:dd:ee:f1", // duplicated mac+net; ignored 266 NetworkTag: "network-vlan42", 267 InterfaceName: "eth2", 268 IsVirtual: true, 269 }, { 270 MACAddress: "aa:bb:cc:dd:ee:f4", 271 NetworkTag: "network-net1", 272 InterfaceName: "eth1", // duplicated name+machine id; ignored 273 IsVirtual: false, 274 }} 275 276 err = apiMachine.SetInstanceInfo("i-will", "fake_nonce", &hwChars, networks, ifaces) 277 c.Assert(err, gc.IsNil) 278 279 instanceId, err = apiMachine.InstanceId() 280 c.Assert(err, gc.IsNil) 281 c.Assert(instanceId, gc.Equals, instance.Id("i-will")) 282 283 // Try it again - should fail. 284 err = apiMachine.SetInstanceInfo("i-wont", "fake", nil, nil, nil) 285 c.Assert(err, gc.ErrorMatches, `aborted instance "i-wont": cannot set instance data for machine "1": already set`) 286 287 // Now try to get machine 0's instance id. 288 apiMachine, err = s.provisioner.Machine(s.machine.Tag()) 289 c.Assert(err, gc.IsNil) 290 instanceId, err = apiMachine.InstanceId() 291 c.Assert(err, gc.IsNil) 292 c.Assert(instanceId, gc.Equals, instance.Id("i-manager")) 293 294 // Check the networks are created. 295 for i, _ := range networks { 296 if i == 3 { 297 // Last one was ignored, so skip it. 298 break 299 } 300 _, networkName, err := names.ParseTag(networks[i].Tag, names.NetworkTagKind) 301 c.Assert(err, gc.IsNil) 302 network, err := s.State.Network(networkName) 303 c.Assert(err, gc.IsNil) 304 c.Check(network.Name(), gc.Equals, networkName) 305 c.Check(network.ProviderId(), gc.Equals, networks[i].ProviderId) 306 c.Check(network.Tag(), gc.Equals, networks[i].Tag) 307 c.Check(network.VLANTag(), gc.Equals, networks[i].VLANTag) 308 c.Check(network.CIDR(), gc.Equals, networks[i].CIDR) 309 } 310 311 // And the network interfaces as well. 312 ifacesMachine, err = notProvisionedMachine.NetworkInterfaces() 313 c.Assert(err, gc.IsNil) 314 c.Assert(ifacesMachine, gc.HasLen, 4) 315 actual := make([]params.NetworkInterface, len(ifacesMachine)) 316 for i, iface := range ifacesMachine { 317 actual[i].InterfaceName = iface.InterfaceName() 318 actual[i].NetworkTag = iface.NetworkTag() 319 actual[i].MACAddress = iface.MACAddress() 320 actual[i].IsVirtual = iface.IsVirtual() 321 c.Check(iface.MachineTag(), gc.Equals, notProvisionedMachine.Tag()) 322 c.Check(iface.MachineId(), gc.Equals, notProvisionedMachine.Id()) 323 } 324 c.Assert(actual, jc.SameContents, ifaces[:4]) // skip the rest as they are ignored. 325 } 326 327 func (s *provisionerSuite) TestSeries(c *gc.C) { 328 // Create a fresh machine with different series. 329 foobarMachine, err := s.State.AddMachine("foobar", state.JobHostUnits) 330 c.Assert(err, gc.IsNil) 331 332 apiMachine, err := s.provisioner.Machine(foobarMachine.Tag()) 333 c.Assert(err, gc.IsNil) 334 series, err := apiMachine.Series() 335 c.Assert(err, gc.IsNil) 336 c.Assert(series, gc.Equals, "foobar") 337 338 // Now try machine 0. 339 apiMachine, err = s.provisioner.Machine(s.machine.Tag()) 340 c.Assert(err, gc.IsNil) 341 series, err = apiMachine.Series() 342 c.Assert(err, gc.IsNil) 343 c.Assert(series, gc.Equals, "quantal") 344 } 345 346 func (s *provisionerSuite) TestDistributionGroup(c *gc.C) { 347 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 348 c.Assert(err, gc.IsNil) 349 instances, err := apiMachine.DistributionGroup() 350 c.Assert(err, gc.IsNil) 351 c.Assert(instances, gc.DeepEquals, []instance.Id{"i-manager"}) 352 353 machine1, err := s.State.AddMachine("quantal", state.JobHostUnits) 354 c.Assert(err, gc.IsNil) 355 apiMachine, err = s.provisioner.Machine(machine1.Tag()) 356 c.Assert(err, gc.IsNil) 357 wordpress := s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) 358 359 err = apiMachine.SetInstanceInfo("i-d", "fake", nil, nil, nil) 360 c.Assert(err, gc.IsNil) 361 instances, err = apiMachine.DistributionGroup() 362 c.Assert(err, gc.IsNil) 363 c.Assert(instances, gc.HasLen, 0) // no units assigned 364 365 var unitNames []string 366 for i := 0; i < 3; i++ { 367 unit, err := wordpress.AddUnit() 368 c.Assert(err, gc.IsNil) 369 unitNames = append(unitNames, unit.Name()) 370 err = unit.AssignToMachine(machine1) 371 c.Assert(err, gc.IsNil) 372 instances, err := apiMachine.DistributionGroup() 373 c.Assert(err, gc.IsNil) 374 c.Assert(instances, gc.DeepEquals, []instance.Id{"i-d"}) 375 } 376 } 377 378 func (s *provisionerSuite) TestDistributionGroupMachineNotFound(c *gc.C) { 379 stateMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 380 c.Assert(err, gc.IsNil) 381 apiMachine, err := s.provisioner.Machine(stateMachine.Tag()) 382 c.Assert(err, gc.IsNil) 383 err = apiMachine.EnsureDead() 384 c.Assert(err, gc.IsNil) 385 err = apiMachine.Remove() 386 c.Assert(err, gc.IsNil) 387 _, err = apiMachine.DistributionGroup() 388 c.Assert(err, gc.ErrorMatches, "machine 1 not found") 389 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 390 } 391 392 func (s *provisionerSuite) TestProvisioningInfo(c *gc.C) { 393 cons := constraints.MustParse("cpu-cores=12 mem=8G networks=^net3,^net4") 394 template := state.MachineTemplate{ 395 Series: "quantal", 396 Jobs: []state.MachineJob{state.JobHostUnits}, 397 Placement: "valid", 398 Constraints: cons, 399 RequestedNetworks: []string{"net1", "net2"}, 400 } 401 machine, err := s.State.AddOneMachine(template) 402 c.Assert(err, gc.IsNil) 403 apiMachine, err := s.provisioner.Machine(machine.Tag()) 404 c.Assert(err, gc.IsNil) 405 provisioningInfo, err := apiMachine.ProvisioningInfo() 406 c.Assert(err, gc.IsNil) 407 c.Assert(provisioningInfo.Series, gc.Equals, template.Series) 408 c.Assert(provisioningInfo.Placement, gc.Equals, template.Placement) 409 c.Assert(provisioningInfo.Constraints, gc.DeepEquals, template.Constraints) 410 c.Assert(provisioningInfo.Networks, gc.DeepEquals, template.RequestedNetworks) 411 } 412 413 func (s *provisionerSuite) TestProvisioningInfoMachineNotFound(c *gc.C) { 414 stateMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 415 c.Assert(err, gc.IsNil) 416 apiMachine, err := s.provisioner.Machine(stateMachine.Tag()) 417 c.Assert(err, gc.IsNil) 418 err = apiMachine.EnsureDead() 419 c.Assert(err, gc.IsNil) 420 err = apiMachine.Remove() 421 c.Assert(err, gc.IsNil) 422 _, err = apiMachine.ProvisioningInfo() 423 c.Assert(err, gc.ErrorMatches, "machine 1 not found") 424 c.Assert(err, jc.Satisfies, params.IsCodeNotFound) 425 // auth tests in apiserver 426 } 427 428 func (s *provisionerSuite) TestWatchContainers(c *gc.C) { 429 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 430 c.Assert(err, gc.IsNil) 431 432 // Add one LXC container. 433 template := state.MachineTemplate{ 434 Series: "quantal", 435 Jobs: []state.MachineJob{state.JobHostUnits}, 436 } 437 container, err := s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) 438 c.Assert(err, gc.IsNil) 439 440 w, err := apiMachine.WatchContainers(instance.LXC) 441 c.Assert(err, gc.IsNil) 442 defer statetesting.AssertStop(c, w) 443 wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) 444 445 // Initial event. 446 wc.AssertChange(container.Id()) 447 448 // Change something other than the containers and make sure it's 449 // not detected. 450 err = apiMachine.SetStatus(params.StatusStarted, "not really", nil) 451 c.Assert(err, gc.IsNil) 452 wc.AssertNoChange() 453 454 // Add a KVM container and make sure it's not detected. 455 container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.KVM) 456 c.Assert(err, gc.IsNil) 457 wc.AssertNoChange() 458 459 // Add another LXC container and make sure it's detected. 460 container, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) 461 c.Assert(err, gc.IsNil) 462 wc.AssertChange(container.Id()) 463 464 statetesting.AssertStop(c, w) 465 wc.AssertClosed() 466 } 467 468 func (s *provisionerSuite) TestWatchContainersAcceptsSupportedContainers(c *gc.C) { 469 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 470 c.Assert(err, gc.IsNil) 471 472 for _, ctype := range instance.ContainerTypes { 473 w, err := apiMachine.WatchContainers(ctype) 474 c.Assert(w, gc.NotNil) 475 c.Assert(err, gc.IsNil) 476 } 477 } 478 479 func (s *provisionerSuite) TestWatchContainersErrors(c *gc.C) { 480 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 481 c.Assert(err, gc.IsNil) 482 483 _, err = apiMachine.WatchContainers(instance.NONE) 484 c.Assert(err, gc.ErrorMatches, `unsupported container type "none"`) 485 486 _, err = apiMachine.WatchContainers("") 487 c.Assert(err, gc.ErrorMatches, "container type must be specified") 488 } 489 490 func (s *provisionerSuite) TestWatchEnvironMachines(c *gc.C) { 491 w, err := s.provisioner.WatchEnvironMachines() 492 c.Assert(err, gc.IsNil) 493 defer statetesting.AssertStop(c, w) 494 wc := statetesting.NewStringsWatcherC(c, s.BackingState, w) 495 496 // Initial event. 497 wc.AssertChange(s.machine.Id()) 498 499 // Add another 2 machines make sure they are detected. 500 otherMachine, err := s.State.AddMachine("quantal", state.JobHostUnits) 501 c.Assert(err, gc.IsNil) 502 otherMachine, err = s.State.AddMachine("quantal", state.JobHostUnits) 503 c.Assert(err, gc.IsNil) 504 wc.AssertChange("1", "2") 505 506 // Change the lifecycle of last machine. 507 err = otherMachine.EnsureDead() 508 c.Assert(err, gc.IsNil) 509 wc.AssertChange("2") 510 511 // Add a container and make sure it's not detected. 512 template := state.MachineTemplate{ 513 Series: "quantal", 514 Jobs: []state.MachineJob{state.JobHostUnits}, 515 } 516 _, err = s.State.AddMachineInsideMachine(template, s.machine.Id(), instance.LXC) 517 c.Assert(err, gc.IsNil) 518 wc.AssertNoChange() 519 520 statetesting.AssertStop(c, w) 521 wc.AssertClosed() 522 } 523 524 func (s *provisionerSuite) TestStateAddresses(c *gc.C) { 525 err := s.machine.SetAddresses(instance.NewAddress("0.1.2.3", instance.NetworkUnknown)) 526 c.Assert(err, gc.IsNil) 527 528 stateAddresses, err := s.State.Addresses() 529 c.Assert(err, gc.IsNil) 530 531 addresses, err := s.provisioner.StateAddresses() 532 c.Assert(err, gc.IsNil) 533 c.Assert(addresses, gc.DeepEquals, stateAddresses) 534 } 535 536 func (s *provisionerSuite) TestContainerManagerConfigKVM(c *gc.C) { 537 args := params.ContainerManagerConfigParams{Type: instance.KVM} 538 result, err := s.provisioner.ContainerManagerConfig(args) 539 c.Assert(err, gc.IsNil) 540 c.Assert(result.ManagerConfig, gc.DeepEquals, map[string]string{ 541 container.ConfigName: "juju", 542 }) 543 } 544 545 func (s *provisionerSuite) TestContainerManagerConfigLXC(c *gc.C) { 546 args := params.ContainerManagerConfigParams{Type: instance.LXC} 547 st, err := state.Open(s.StateInfo(c), state.DialOpts{}, state.Policy(nil)) 548 c.Assert(err, gc.IsNil) 549 defer st.Close() 550 551 tests := []struct { 552 lxcUseClone bool 553 lxcUseCloneAufs bool 554 expectedUseClone string 555 expectedUseCloneAufs string 556 }{{ 557 lxcUseClone: true, 558 expectedUseClone: "true", 559 expectedUseCloneAufs: "false", 560 }, { 561 lxcUseClone: false, 562 expectedUseClone: "false", 563 expectedUseCloneAufs: "false", 564 }, { 565 lxcUseCloneAufs: false, 566 expectedUseClone: "false", 567 expectedUseCloneAufs: "false", 568 }, { 569 lxcUseClone: true, 570 lxcUseCloneAufs: true, 571 expectedUseClone: "true", 572 expectedUseCloneAufs: "true", 573 }} 574 575 result, err := s.provisioner.ContainerManagerConfig(args) 576 c.Assert(err, gc.IsNil) 577 c.Assert(result.ManagerConfig[container.ConfigName], gc.Equals, "juju") 578 c.Assert(result.ManagerConfig["use-clone"], gc.Equals, "") 579 580 // Change lxc-clone, and ensure it gets picked up. 581 for i, t := range tests { 582 c.Logf("test %d: %+v", i, t) 583 err = st.UpdateEnvironConfig(map[string]interface{}{ 584 "lxc-clone": t.lxcUseClone, 585 "lxc-clone-aufs": t.lxcUseCloneAufs, 586 }, nil, nil) 587 c.Assert(err, gc.IsNil) 588 result, err := s.provisioner.ContainerManagerConfig(args) 589 c.Assert(err, gc.IsNil) 590 c.Assert(result.ManagerConfig[container.ConfigName], gc.Equals, "juju") 591 c.Assert(result.ManagerConfig["use-clone"], gc.Equals, t.expectedUseClone) 592 c.Assert(result.ManagerConfig["use-aufs"], gc.Equals, t.expectedUseCloneAufs) 593 } 594 } 595 596 func (s *provisionerSuite) TestContainerManagerConfigPermissive(c *gc.C) { 597 // ContainerManagerConfig is permissive of container types, and 598 // will just return the basic type-independent configuration. 599 args := params.ContainerManagerConfigParams{Type: "invalid"} 600 result, err := s.provisioner.ContainerManagerConfig(args) 601 c.Assert(err, gc.IsNil) 602 c.Assert(result.ManagerConfig, gc.DeepEquals, map[string]string{ 603 container.ConfigName: "juju", 604 }) 605 } 606 607 func (s *provisionerSuite) TestContainerConfig(c *gc.C) { 608 result, err := s.provisioner.ContainerConfig() 609 c.Assert(err, gc.IsNil) 610 c.Assert(result.ProviderType, gc.Equals, "dummy") 611 c.Assert(result.AuthorizedKeys, gc.Equals, coretesting.FakeAuthKeys) 612 c.Assert(result.SSLHostnameVerification, jc.IsTrue) 613 } 614 615 func (s *provisionerSuite) TestToolsWrongMachine(c *gc.C) { 616 tools, err := s.provisioner.Tools("42") 617 c.Assert(err, gc.ErrorMatches, "permission denied") 618 c.Assert(err, jc.Satisfies, params.IsCodeUnauthorized) 619 c.Assert(tools, gc.IsNil) 620 } 621 622 func (s *provisionerSuite) TestTools(c *gc.C) { 623 cur := version.Current 624 curTools := &tools.Tools{Version: cur, URL: ""} 625 curTools.Version.Minor++ 626 s.machine.SetAgentVersion(cur) 627 // Provisioner.Tools returns the *desired* set of tools, not the 628 // currently running set. We want to be upgraded to cur.Version 629 stateTools, err := s.provisioner.Tools(s.machine.Tag()) 630 c.Assert(err, gc.IsNil) 631 c.Assert(stateTools.Version, gc.Equals, cur) 632 c.Assert(stateTools.URL, gc.Not(gc.Equals), "") 633 } 634 635 func (s *provisionerSuite) TestSetSupportedContainers(c *gc.C) { 636 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 637 c.Assert(err, gc.IsNil) 638 err = apiMachine.SetSupportedContainers(instance.LXC, instance.KVM) 639 c.Assert(err, gc.IsNil) 640 641 err = s.machine.Refresh() 642 c.Assert(err, gc.IsNil) 643 containers, ok := s.machine.SupportedContainers() 644 c.Assert(ok, jc.IsTrue) 645 c.Assert(containers, gc.DeepEquals, []instance.ContainerType{instance.LXC, instance.KVM}) 646 } 647 648 func (s *provisionerSuite) TestSupportsNoContainers(c *gc.C) { 649 apiMachine, err := s.provisioner.Machine(s.machine.Tag()) 650 c.Assert(err, gc.IsNil) 651 err = apiMachine.SupportsNoContainers() 652 c.Assert(err, gc.IsNil) 653 654 err = s.machine.Refresh() 655 c.Assert(err, gc.IsNil) 656 containers, ok := s.machine.SupportedContainers() 657 c.Assert(ok, jc.IsTrue) 658 c.Assert(containers, gc.DeepEquals, []instance.ContainerType{}) 659 }