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