func (s *UnitSuite) TestRemoveUnitMachineRetryOrCond(c *gc.C) { host, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) target, err := s.service.AddUnit() c.Assert(err, jc.ErrorIsNil) c.Assert(target.AssignToMachine(host), gc.IsNil) // This unit will be colocated in the transaction hook to cause a retry. colocated, err := s.service.AddUnit() c.Assert(err, jc.ErrorIsNil) c.Assert(host.SetHasVote(true), gc.IsNil) defer state.SetTestHooks(c, s.State, jujutxn.TestHook{ Before: func() { hostHandle, err := s.State.Machine(host.Id()) c.Assert(err, jc.ErrorIsNil) // Original assertion preventing host removal is no longer valid c.Assert(hostHandle.SetHasVote(false), gc.IsNil) // But now the host gets a colocated unit, a different condition preventing removal c.Assert(colocated.AssignToMachine(hostHandle), gc.IsNil) }, }).Check() c.Assert(target.Destroy(), gc.IsNil) assertLife(c, host, state.Alive) }
func (s *UnitSuite) TestRemoveUnitMachineRetryContainer(c *gc.C) { host, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) target, err := s.service.AddUnit() c.Assert(err, jc.ErrorIsNil) c.Assert(target.AssignToMachine(host), gc.IsNil) defer state.SetTestHooks(c, s.State, jujutxn.TestHook{ Before: func() { machine, err := s.State.AddMachineInsideMachine(state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, }, host.Id(), instance.LXC) c.Assert(err, jc.ErrorIsNil) assertLife(c, machine, state.Alive) // test-setup verification for the disqualifying machine. hostHandle, err := s.State.Machine(host.Id()) c.Assert(err, jc.ErrorIsNil) containers, err := hostHandle.Containers() c.Assert(err, jc.ErrorIsNil) c.Assert(containers, gc.HasLen, 1) }, }).Check() c.Assert(target.Destroy(), gc.IsNil) assertLife(c, host, state.Alive) }
func (s *AssignSuite) TestAssignUnitToNewMachineBecomesHost(c *gc.C) { _, err := s.State.AddMachine("quantal", state.JobManageModel) // bootstrap machine c.Assert(err, jc.ErrorIsNil) // Set up constraints to specify we want to install into a container. econs := constraints.MustParse("container=lxc") err = s.State.SetModelConstraints(econs) c.Assert(err, jc.ErrorIsNil) // Create a unit and a clean machine. unit, err := s.wordpress.AddUnit() c.Assert(err, jc.ErrorIsNil) machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) addContainer := txn.TestHook{ Before: func() { _, err := s.State.AddMachineInsideMachine(state.MachineTemplate{ Series: "quantal", Jobs: []state.MachineJob{state.JobHostUnits}, }, machine.Id(), instance.LXC) c.Assert(err, jc.ErrorIsNil) }, } defer state.SetTestHooks(c, s.State, addContainer).Check() err = unit.AssignToNewMachineOrContainer() c.Assert(err, jc.ErrorIsNil) mid, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) c.Assert(mid, gc.Equals, "2/lxc/0") }
func (s *AssignSuite) TestAssignUnitToNewMachineBecomesDirty(c *gc.C) { _, err := s.State.AddMachine("quantal", state.JobManageModel) // bootstrap machine c.Assert(err, jc.ErrorIsNil) // Set up constraints to specify we want to install into a container. econs := constraints.MustParse("container=lxc") err = s.State.SetModelConstraints(econs) c.Assert(err, jc.ErrorIsNil) // Create some units and a clean machine. unit, err := s.wordpress.AddUnit() c.Assert(err, jc.ErrorIsNil) anotherUnit, err := s.wordpress.AddUnit() c.Assert(err, jc.ErrorIsNil) machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) makeDirty := txn.TestHook{ Before: func() { c.Assert(unit.AssignToMachine(machine), gc.IsNil) }, } defer state.SetTestHooks(c, s.State, makeDirty).Check() err = anotherUnit.AssignToNewMachineOrContainer() c.Assert(err, jc.ErrorIsNil) mid, err := unit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) c.Assert(mid, gc.Equals, "1") mid, err = anotherUnit.AssignedMachineId() c.Assert(err, jc.ErrorIsNil) c.Assert(mid, gc.Equals, "2/lxc/0") }
func (s *linkLayerDevicesStateSuite) TestSetLinkLayerDevicesWithTooMuchStateChurn(c *gc.C) { childArgs, churnHook := s.prepareSetLinkLayerDevicesWithStateChurn(c) defer state.SetTestHooks(c, s.State, churnHook, churnHook, churnHook).Check() s.assertAllLinkLayerDevicesOnMachineMatchCount(c, s.machine, 1) // parent only err := s.machine.SetLinkLayerDevices(childArgs) c.Assert(errors.Cause(err), gc.Equals, jujutxn.ErrExcessiveContention) s.assertAllLinkLayerDevicesOnMachineMatchCount(c, s.machine, 1) // only the parent remains }
func (s *linkLayerDevicesStateSuite) TestSetLinkLayerDevicesWithModerateStateChurn(c *gc.C) { childArgs, churnHook := s.prepareSetLinkLayerDevicesWithStateChurn(c) defer state.SetTestHooks(c, s.State, churnHook, churnHook).Check() s.assertAllLinkLayerDevicesOnMachineMatchCount(c, s.machine, 1) // parent only err := s.machine.SetLinkLayerDevices(childArgs) c.Assert(err, jc.ErrorIsNil) s.assertAllLinkLayerDevicesOnMachineMatchCount(c, s.machine, 2) // both parent and child remain }
func (s *ActionSuite) TestAddActionFailsOnDeadUnitInTransaction(c *gc.C) { unit, err := s.State.Unit(s.unit.Name()) c.Assert(err, jc.ErrorIsNil) preventUnitDestroyRemove(c, unit) killUnit := txn.TestHook{ Before: func() { c.Assert(unit.Destroy(), gc.IsNil) c.Assert(unit.EnsureDead(), gc.IsNil) }, } defer state.SetTestHooks(c, s.State, killUnit).Check() _, err = unit.AddAction("snapshot", map[string]interface{}{}) c.Assert(err, gc.Equals, state.ErrDead) }
func (s *RestoreInfoSuite) TestUpdateRaceExhaustion(c *gc.C) { s.setupPending(c) perturb := jujutxn.TestHook{ Before: func() { s.checkSetStatus(c, state.RestoreFailed) }, After: func() { s.checkSetStatus(c, state.RestorePending) }, } defer state.SetTestHooks( c, s.State, perturb, perturb, perturb, ).Check() err := s.info.SetStatus(state.RestoreInProgress) c.Check(err, gc.ErrorMatches, "setting status \"RESTORING\": state changing too quickly; try again soon") }
func (s *UnitSuite) TestRemoveUnitMachineThrashed(c *gc.C) { host, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) target, err := s.service.AddUnit() c.Assert(err, jc.ErrorIsNil) c.Assert(target.AssignToMachine(host), gc.IsNil) flip := jujutxn.TestHook{ Before: func() { s.setMachineVote(c, host.Id(), true) }, } flop := jujutxn.TestHook{ Before: func() { s.setMachineVote(c, host.Id(), false) }, } // You'll need to adjust the flip-flops to match the number of transaction // retries. defer state.SetTestHooks(c, s.State, flip, flop, flip).Check() c.Assert(target.Destroy(), gc.ErrorMatches, "state changing too quickly; try again soon") }
func (s *UnitSuite) TestSetCharmURLRetriesWithDifferentURL(c *gc.C) { sch := s.AddConfigCharm(c, "wordpress", emptyConfig, 2) defer state.SetTestHooks(c, s.State, jujutxn.TestHook{ Before: func() { // Set a different charm to force a retry: first on // the service, so the settings are created, then on // the unit. err := s.service.SetCharm(sch, false, false) c.Assert(err, jc.ErrorIsNil) err = s.unit.SetCharmURL(sch.URL()) c.Assert(err, jc.ErrorIsNil) }, After: func() { // Set back the same charm on the service, so the // settings refcount is correct.. err := s.service.SetCharm(s.charm, false, false) c.Assert(err, jc.ErrorIsNil) }, }, jujutxn.TestHook{ Before: nil, // Ensure there will be a retry. After: func() { // Verify it worked after the second attempt. err := s.unit.Refresh() c.Assert(err, jc.ErrorIsNil) currentURL, hasURL := s.unit.CharmURL() c.Assert(currentURL, jc.DeepEquals, s.charm.URL()) c.Assert(hasURL, jc.IsTrue) }, }, ).Check() err := s.unit.SetCharmURL(s.charm.URL()) c.Assert(err, jc.ErrorIsNil) }