func (s *AssignSuite) TestAssignUnitToNewMachineSetsConstraints(c *gc.C) { // Set up constraints. scons := constraints.MustParse("mem=2G cpu-power=400") err := s.wordpress.SetConstraints(scons) c.Assert(err, gc.IsNil) econs := constraints.MustParse("mem=4G cpu-cores=2") err = s.State.SetEnvironConstraints(econs) c.Assert(err, gc.IsNil) // Unit will take combined service/environ constraints on creation. unit, err := s.wordpress.AddUnit() c.Assert(err, gc.IsNil) // Change service/env constraints before assigning, to verify this. scons = constraints.MustParse("mem=6G cpu-power=800") err = s.wordpress.SetConstraints(scons) c.Assert(err, gc.IsNil) econs = constraints.MustParse("cpu-cores=4") err = s.State.SetEnvironConstraints(econs) c.Assert(err, gc.IsNil) // The new machine takes the original combined unit constraints. err = unit.AssignToNewMachine() c.Assert(err, gc.IsNil) err = unit.Refresh() c.Assert(err, gc.IsNil) mid, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) machine, err := s.State.Machine(mid) c.Assert(err, gc.IsNil) mcons, err := machine.Constraints() c.Assert(err, gc.IsNil) expect := constraints.MustParse("mem=2G cpu-cores=2 cpu-power=400") c.Assert(mcons, gc.DeepEquals, expect) }
func (s *DeployLocalSuite) TestDeployForceMachineIdWithContainer(c *gc.C) { machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) c.Assert(machine.Id(), gc.Equals, "0") cons := constraints.MustParse("mem=2G") err = s.State.SetEnvironConstraints(cons) c.Assert(err, gc.IsNil) serviceCons := constraints.MustParse("cpu-cores=2") service, err := juju.DeployService(s.State, juju.DeployServiceParams{ ServiceName: "bob", Charm: s.charm, Constraints: serviceCons, NumUnits: 1, ToMachineSpec: fmt.Sprintf("%s:0", instance.LXC), }) c.Assert(err, gc.IsNil) s.assertConstraints(c, service, serviceCons) units, err := service.AllUnits() c.Assert(err, gc.IsNil) c.Assert(units, gc.HasLen, 1) // The newly created container will use the constraints. id, err := units[0].AssignedMachineId() c.Assert(err, gc.IsNil) machine, err = s.State.Machine(id) c.Assert(err, gc.IsNil) expectedCons, err := machine.Constraints() c.Assert(err, gc.IsNil) c.Assert(cons, gc.DeepEquals, expectedCons) }
func (s *ConstraintsSuite) TestWithout(c *gc.C) { for i, t := range withoutTests { c.Logf("test %d", i) initial := constraints.MustParse(t.initial) final, err := constraints.Without(initial, t.without...) c.Assert(err, gc.IsNil) c.Check(final, gc.DeepEquals, constraints.MustParse(t.final)) } }
func (t *localServerSuite) TestConstraintsMerge(c *gc.C) { env := t.Prepare(c) validator, err := env.ConstraintsValidator() c.Assert(err, gc.IsNil) consA := constraints.MustParse("arch=amd64 mem=1G cpu-power=10 cpu-cores=2 tags=bar") consB := constraints.MustParse("arch=i386 instance-type=m1.small") cons, err := validator.Merge(consA, consB) c.Assert(err, gc.IsNil) c.Assert(cons, gc.DeepEquals, constraints.MustParse("arch=i386 instance-type=m1.small tags=bar")) }
func (s *validationSuite) TestMergeError(c *gc.C) { validator := constraints.NewValidator() validator.RegisterConflicts([]string{"instance-type"}, []string{"mem"}) consFallback := constraints.MustParse("instance-type=foo mem=4G") cons := constraints.MustParse("cpu-cores=2") _, err := validator.Merge(consFallback, cons) c.Assert(err, gc.ErrorMatches, `ambiguous constraints: "mem" overlaps with "instance-type"`) _, err = validator.Merge(cons, consFallback) c.Assert(err, gc.ErrorMatches, `ambiguous constraints: "mem" overlaps with "instance-type"`) }
func (s *localServerSuite) TestConstraintsMerge(c *gc.C) { env := s.Open(c) validator, err := env.ConstraintsValidator() c.Assert(err, gc.IsNil) consA := constraints.MustParse("arch=amd64 mem=1G root-disk=10G") consB := constraints.MustParse("instance-type=m1.small") cons, err := validator.Merge(consA, consB) c.Assert(err, gc.IsNil) c.Assert(cons, gc.DeepEquals, constraints.MustParse("instance-type=m1.small")) }
func (t *localServerSuite) TestConstraintsValidatorVocab(c *gc.C) { env := t.Prepare(c) validator, err := env.ConstraintsValidator() c.Assert(err, gc.IsNil) cons := constraints.MustParse("arch=ppc64") _, err = validator.Validate(cons) c.Assert(err, gc.ErrorMatches, "invalid constraint value: arch=ppc64\nvalid values are:.*") cons = constraints.MustParse("instance-type=foo") _, err = validator.Validate(cons) c.Assert(err, gc.ErrorMatches, "invalid constraint value: instance-type=foo\nvalid values are:.*") }
func (s *constraintsValidationSuite) TestMachineConstraints(c *gc.C) { for i, t := range setConstraintsTests { c.Logf("test %d", i) err := s.State.SetEnvironConstraints(constraints.MustParse(t.consFallback)) c.Check(err, gc.IsNil) m, err := s.addOneMachine(c, constraints.MustParse(t.cons)) c.Check(err, gc.IsNil) cons, err := m.Constraints() c.Check(err, gc.IsNil) c.Check(cons, gc.DeepEquals, constraints.MustParse(t.expected)) } }
func (s *DeployLocalSuite) TestDeployConstraints(c *gc.C) { err := s.State.SetEnvironConstraints(constraints.MustParse("mem=2G")) c.Assert(err, gc.IsNil) serviceCons := constraints.MustParse("cpu-cores=2") service, err := juju.DeployService(s.State, juju.DeployServiceParams{ ServiceName: "bob", Charm: s.charm, Constraints: serviceCons, }) c.Assert(err, gc.IsNil) s.assertConstraints(c, service, serviceCons) }
func (s *validationSuite) TestMerge(c *gc.C) { for i, t := range mergeTests { c.Logf("test %d: %s", i, t.desc) validator := constraints.NewValidator() validator.RegisterConflicts(t.reds, t.blues) consFallback := constraints.MustParse(t.consFallback) cons := constraints.MustParse(t.cons) merged, err := validator.Merge(consFallback, cons) c.Assert(err, gc.IsNil) expected := constraints.MustParse(t.expected) c.Check(merged, gc.DeepEquals, expected) } }
func (s *assignCleanSuite) TestAssignUsingConstraintsToMachine(c *gc.C) { for i, t := range assignUsingConstraintsTests { c.Logf("test %d", i) cons := constraints.MustParse(t.unitConstraints) err := s.State.SetEnvironConstraints(cons) c.Assert(err, gc.IsNil) unit, err := s.wordpress.AddUnit() c.Assert(err, gc.IsNil) m, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) if t.hardwareCharacteristics != "none" { hc := instance.MustParseHardware(t.hardwareCharacteristics) err = m.SetProvisioned("inst-id", "fake_nonce", &hc) c.Assert(err, gc.IsNil) } um, err := s.assignUnit(unit) if t.assignOk { c.Assert(err, gc.IsNil) c.Assert(um.Id(), gc.Equals, m.Id()) } else { c.Assert(um, gc.IsNil) c.Assert(err, gc.ErrorMatches, eligibleMachinesInUse) // Destroy the machine so it can't be used for the next test. err = m.Destroy() c.Assert(err, gc.IsNil) } } }
func (s *ConstraintsSuite) TestHasContainer(c *gc.C) { for i, t := range hasContainerTests { c.Logf("test %d", i) cons := constraints.MustParse(t.constraints) c.Check(cons.HasContainer(), gc.Equals, t.hasContainer) } }
func (s *AssignSuite) TestAssignUnitToNewMachineBecomesDirty(c *gc.C) { _, err := s.State.AddMachine("quantal", state.JobManageEnviron) // bootstrap machine c.Assert(err, gc.IsNil) // Set up constraints to specify we want to install into a container. econs := constraints.MustParse("container=lxc") err = s.State.SetEnvironConstraints(econs) c.Assert(err, gc.IsNil) // Create some units and a clean machine. unit, err := s.wordpress.AddUnit() c.Assert(err, gc.IsNil) anotherUnit, err := s.wordpress.AddUnit() c.Assert(err, gc.IsNil) machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) makeDirty := state.TransactionHook{ Before: func() { c.Assert(unit.AssignToMachine(machine), gc.IsNil) }, } defer state.SetTransactionHooks( c, s.State, makeDirty, ).Check() err = anotherUnit.AssignToNewMachineOrContainer() c.Assert(err, gc.IsNil) mid, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) c.Assert(mid, gc.Equals, "1") mid, err = anotherUnit.AssignedMachineId() c.Assert(err, gc.IsNil) c.Assert(mid, gc.Equals, "2/lxc/0") }
func (s *AssignSuite) TestAssignUnitToNewMachineBecomesHost(c *gc.C) { _, err := s.State.AddMachine("quantal", state.JobManageEnviron) // bootstrap machine c.Assert(err, gc.IsNil) // Set up constraints to specify we want to install into a container. econs := constraints.MustParse("container=lxc") err = s.State.SetEnvironConstraints(econs) c.Assert(err, gc.IsNil) // Create a unit and a clean machine. unit, err := s.wordpress.AddUnit() c.Assert(err, gc.IsNil) machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, gc.IsNil) addContainer := state.TransactionHook{ Before: func() { _, err := s.State.AddMachineInsideMachine(state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, }, machine.Id(), instance.LXC) c.Assert(err, gc.IsNil) }, } defer state.SetTransactionHooks( c, s.State, addContainer, ).Check() err = unit.AssignToNewMachineOrContainer() c.Assert(err, gc.IsNil) mid, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) c.Assert(mid, gc.Equals, "2/lxc/0") }
func (s *AssignSuite) TestAssignUnitToNewMachineDefaultContainerConstraint(c *gc.C) { // Set up env constraints. econs := constraints.MustParse("container=lxc") err := s.State.SetEnvironConstraints(econs) c.Assert(err, gc.IsNil) s.assertAssignUnitToNewMachineContainerConstraint(c) }
func (s *withoutStateServerSuite) TestConstraints(c *gc.C) { // Add a machine with some constraints. template := state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: constraints.MustParse("cpu-cores=123", "mem=8G"), } consMachine, err := s.State.AddOneMachine(template) c.Assert(err, gc.IsNil) machine0Constraints, err := s.machines[0].Constraints() c.Assert(err, gc.IsNil) args := params.Entities{Entities: []params.Entity{ {Tag: s.machines[0].Tag()}, {Tag: consMachine.Tag()}, {Tag: "machine-42"}, {Tag: "unit-foo-0"}, {Tag: "service-bar"}, }} result, err := s.provisioner.Constraints(args) c.Assert(err, gc.IsNil) c.Assert(result, gc.DeepEquals, params.ConstraintsResults{ Results: []params.ConstraintsResult{ {Constraints: machine0Constraints}, {Constraints: template.Constraints}, {Error: apiservertesting.NotFoundError("machine 42")}, {Error: apiservertesting.ErrUnauthorized}, {Error: apiservertesting.ErrUnauthorized}, }, }) }
func (s *getSuite) TestServiceGet(c *gc.C) { for i, t := range getTests { c.Logf("test %d. %s", i, t.about) ch := s.AddTestingCharm(c, t.charm) svc := s.AddTestingService(c, fmt.Sprintf("test%d", i), ch) var constraintsv constraints.Value if t.constraints != "" { constraintsv = constraints.MustParse(t.constraints) err := svc.SetConstraints(constraintsv) c.Assert(err, gc.IsNil) } if t.config != nil { err := svc.UpdateConfigSettings(t.config) c.Assert(err, gc.IsNil) } expect := t.expect expect.Constraints = constraintsv expect.Service = svc.Name() expect.Charm = ch.Meta().Name apiclient := s.APIState.Client() got, err := apiclient.ServiceGet(svc.Name()) c.Assert(err, gc.IsNil) c.Assert(*got, gc.DeepEquals, expect) } }
func (s *AssignSuite) TestAssignUnitToNewMachineContainerConstraint(c *gc.C) { // Set up service constraints. scons := constraints.MustParse("container=lxc") err := s.wordpress.SetConstraints(scons) c.Assert(err, gc.IsNil) s.assertAssignUnitToNewMachineContainerConstraint(c) }
func (s *instanceTypeSuite) TestFindInstanceSpec(c *gc.C) { env := s.setupEnvWithDummyMetadata(c) for i, t := range findInstanceSpecTests { c.Logf("test %d", i) cons := constraints.MustParse(t.cons) constraints := &instances.InstanceConstraint{ Region: "West US", Series: t.series, Arches: []string{"amd64"}, Constraints: cons, } // Find a matching instance type and image. spec, err := findInstanceSpec(env, constraints) c.Assert(err, gc.IsNil) // We got the instance type we described in our constraints, and // the image returned by (the fake) simplestreams. if cons.HasInstanceType() { c.Check(spec.InstanceType.Name, gc.Equals, *cons.InstanceType) } else { c.Check(spec.InstanceType.Name, gc.Equals, t.itype) } c.Check(spec.Image.Id, gc.Equals, "image-id") } }
func (s *instanceTypeSuite) TestPrecheckInstanceValidInstanceType(c *gc.C) { env := s.setupEnvWithDummyMetadata(c) cons := constraints.MustParse("instance-type=Large") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.IsNil) }
func (s *localServerSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) { env := s.Open(c) cons := constraints.MustParse("instance-type=m1.large") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.ErrorMatches, `invalid Openstack flavour "m1.large" specified`) }
func (s *instanceTypeSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) { env := s.setupEnvWithDummyMetadata(c) cons := constraints.MustParse("instance-type=Super") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.ErrorMatches, `invalid Azure instance "Super" specified`) }
func (s *BootstrapSuite) TestCannotStartInstance(c *gc.C) { checkPlacement := "directive" checkCons := constraints.MustParse("mem=8G") startInstance := func( placement string, cons constraints.Value, _, _ []string, possibleTools tools.List, mcfg *cloudinit.MachineConfig, ) ( instance.Instance, *instance.HardwareCharacteristics, []network.Info, error, ) { c.Assert(placement, gc.DeepEquals, checkPlacement) c.Assert(cons, gc.DeepEquals, checkCons) c.Assert(mcfg, gc.DeepEquals, environs.NewBootstrapMachineConfig(mcfg.SystemPrivateSSHKey)) return nil, nil, nil, fmt.Errorf("meh, not started") } env := &mockEnviron{ storage: newStorage(s, c), startInstance: startInstance, config: configGetter(c), } ctx := coretesting.Context(c) err := common.Bootstrap(ctx, env, environs.BootstrapParams{ Constraints: checkCons, Placement: checkPlacement, }) c.Assert(err, gc.ErrorMatches, "cannot start bootstrap instance: meh, not started") }
func (t *localServerSuite) TestPrecheckInstanceUnsupportedArch(c *gc.C) { env := t.Prepare(c) cons := constraints.MustParse("instance-type=cc1.4xlarge arch=i386") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.ErrorMatches, `invalid AWS instance type "cc1.4xlarge" and arch "i386" specified`) }
func (s *constraintsValidationSuite) TestServiceConstraints(c *gc.C) { charm := s.AddTestingCharm(c, "wordpress") service := s.AddTestingService(c, "wordpress", charm) for i, t := range setConstraintsTests { c.Logf("test %d", i) err := s.State.SetEnvironConstraints(constraints.MustParse(t.consFallback)) c.Check(err, gc.IsNil) err = service.SetConstraints(constraints.MustParse(t.cons)) c.Check(err, gc.IsNil) u, err := service.AddUnit() c.Check(err, gc.IsNil) cons, err := state.UnitConstraints(u) c.Check(err, gc.IsNil) c.Check(*cons, gc.DeepEquals, constraints.MustParse(t.expected)) } }
func (t *localServerSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) { env := t.Prepare(c) cons := constraints.MustParse("instance-type=m1.invalid") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.ErrorMatches, `invalid AWS instance type "m1.invalid" specified`) }
func (t *localServerSuite) TestPrecheckInstanceValidInstanceType(c *gc.C) { env := t.Prepare(c) cons := constraints.MustParse("instance-type=m1.small root-disk=1G") placement := "" err := env.PrecheckInstance("precise", cons, placement) c.Assert(err, gc.IsNil) }
func (suite *environSuite) TestConstraintsValidatorVocab(c *gc.C) { env := suite.makeEnviron() validator, err := env.ConstraintsValidator() c.Assert(err, gc.IsNil) cons := constraints.MustParse("arch=ppc64") _, err = validator.Validate(cons) c.Assert(err, gc.ErrorMatches, "invalid constraint value: arch=ppc64\nvalid values are:.*") }
func (s *environSuite) TestConstraintsValidator(c *gc.C) { validator, err := s.env.ConstraintsValidator() c.Assert(err, gc.IsNil) cons := constraints.MustParse("arch=amd64 instance-type=foo tags=bar cpu-power=10 cpu-cores=2 mem=1G") unsupported, err := validator.Validate(cons) c.Assert(err, gc.IsNil) c.Assert(unsupported, gc.DeepEquals, []string{"cpu-power", "instance-type", "tags"}) }
func (s *ConstraintsSuite) TestHasAny(c *gc.C) { for i, t := range hasAnyTests { c.Logf("test %d", i) cons := constraints.MustParse(t.cons) obtained := constraints.HasAny(cons, t.attrs...) c.Check(obtained, gc.DeepEquals, t.expected) } }