func (s *FilesystemStateSuite) testFilesystemAttachmentParamsConcurrent(c *gc.C, locBefore, locAfter, expectErr string) { machine, err := s.State.AddMachine("quantal", state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) storage := map[string]state.StorageConstraints{ "data": makeStorageCons("rootfs", 1024, 1), } deploy := func(rev int, location, serviceName string) error { ch := s.createStorageCharmRev(c, "storage-filesystem", charm.Storage{ Name: "data", Type: charm.StorageFilesystem, CountMin: 1, CountMax: 1, Location: location, }, rev) service := s.AddTestingServiceWithStorage(c, serviceName, ch, storage) unit, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) return unit.AssignToMachine(machine) } defer state.SetBeforeHooks(c, s.State, func() { err := deploy(1, locBefore, "storage-filesystem-before") c.Assert(err, jc.ErrorIsNil) }).Check() err = deploy(2, locAfter, "storage-filesystem-after") if expectErr != "" { c.Assert(err, gc.ErrorMatches, expectErr) } else { c.Assert(err, jc.ErrorIsNil) } }
func (s *ModelSuite) TestDestroyControllerRemoveEmptyAddNonEmptyModel(c *gc.C) { st2 := s.Factory.MakeModel(c, nil) defer st2.Close() // Simulate an empty model being removed, and a new non-empty // model being added, just before the remove txn is called. defer state.SetBeforeHooks(c, s.State, func() { // Destroy the empty model, which should move it right // along to Dead, and then remove it. model, err := st2.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(model.Destroy(), jc.ErrorIsNil) err = st2.RemoveAllModelDocs() c.Assert(err, jc.ErrorIsNil) // Add a new, non-empty model. This should still prevent // the controller from being destroyed. st3 := s.Factory.MakeModel(c, nil) defer st3.Close() factory.NewFactory(st3).MakeService(c, nil) }).Check() env, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy model: hosting 1 other models") }
func (s *FilesystemStateSuite) TestFilesystemAttachmentParamsConcurrentRemove(c *gc.C) { // this creates a filesystem mounted at "/srv". filesystem, machine := s.setupFilesystemAttachment(c, "rootfs") ch := s.createStorageCharm(c, "storage-filesystem", charm.Storage{ Name: "data", Type: charm.StorageFilesystem, CountMin: 1, CountMax: 1, Location: "/not/in/srv", }) service := s.AddTestingService(c, "storage-filesystem", ch) unit, err := service.AddUnit() c.Assert(err, jc.ErrorIsNil) defer state.SetBeforeHooks(c, s.State, func() { err := s.State.DetachFilesystem(machine.MachineTag(), filesystem.FilesystemTag()) c.Assert(err, jc.ErrorIsNil) err = s.State.RemoveFilesystemAttachment( machine.MachineTag(), filesystem.FilesystemTag(), ) c.Assert(err, jc.ErrorIsNil) }).Check() err = unit.AssignToMachine(machine) c.Assert(err, jc.ErrorIsNil) }
func (s *UpgradeSuite) TestSetControllerDoneMultipleServersRace(c *gc.C) { v100 := vers("1.0.0") v200 := vers("2.0.0") serverIdB, serverIdC := s.addControllers(c) s.provision(c, serverIdB, serverIdC) info, err := s.State.EnsureUpgradeInfo(s.serverIdA, v100, v200) c.Assert(err, jc.ErrorIsNil) _, err = s.State.EnsureUpgradeInfo(serverIdB, v100, v200) c.Assert(err, jc.ErrorIsNil) _, err = s.State.EnsureUpgradeInfo(serverIdC, v100, v200) c.Assert(err, jc.ErrorIsNil) s.setToFinishing(c, info) // Interrupt the transaction for controller A twice with calls // from the other machines. defer state.SetBeforeHooks(c, s.State, func() { err = info.SetControllerDone(serverIdB) c.Assert(err, jc.ErrorIsNil) }, func() { err = info.SetControllerDone(serverIdC) c.Assert(err, jc.ErrorIsNil) }).Check() err = info.SetControllerDone(s.serverIdA) c.Assert(err, jc.ErrorIsNil) s.assertUpgrading(c, false) info = s.getOneUpgradeInfo(c) c.Assert(info.Status(), gc.Equals, state.UpgradeComplete) c.Assert(info.ControllersDone(), jc.SameContents, []string{"0", "1", "2"}) }
func (s *MachineRemovalSuite) TestMarkForRemovalAssertsMachineStillExists(c *gc.C) { m := s.makeMachine(c, true) defer state.SetBeforeHooks(c, s.State, func() { c.Assert(m.Remove(), gc.IsNil) }).Check() err := m.MarkForRemoval() c.Assert(err, gc.ErrorMatches, "cannot remove machine 0: machine 0 not found") }
//-------------------------------------- // Whitebox race tests to trigger different paths through the SetStatus // code; use arbitrary sample transitions, full set of valid transitions // are checked further down. func (s *RestoreInfoSuite) TestInsertRaceHarmless(c *gc.C) { defer state.SetBeforeHooks( c, s.State, func() { s.checkSetStatus(c, state.RestorePending) }, ).Check() s.checkSetStatus(c, state.RestorePending) }
func (s *MinUnitsSuite) testEnsureMinUnitsBefore(c *gc.C, f func(), minUnits, expectedUnits int) { service := s.service err := service.SetMinUnits(minUnits) c.Assert(err, jc.ErrorIsNil) defer state.SetBeforeHooks(c, s.State, f).Check() err = service.EnsureMinUnits() c.Assert(err, jc.ErrorIsNil) assertAllUnits(c, service, expectedUnits) }
func (s *RestoreInfoSuite) TestUpdateRaceHarmless(c *gc.C) { s.setupInProgress(c) defer state.SetBeforeHooks( c, s.State, func() { s.checkSetStatus(c, state.RestoreFinished) }, ).Check() s.checkSetStatus(c, state.RestoreFinished) }
func (s *RestoreInfoSuite) TestInsertRaceFailure(c *gc.C) { defer state.SetBeforeHooks( c, s.State, func() { s.checkSetStatus(c, state.RestorePending) s.checkSetStatus(c, state.RestoreInProgress) }, ).Check() s.checkBadSetStatus(c, state.RestorePending) s.checkStatus(c, state.RestoreInProgress) }
func (s *MinUnitsSuite) TestEnsureMinUnitsDestroyServiceBefore(c *gc.C) { s.addUnits(c, 1) err := s.service.SetMinUnits(42) c.Assert(err, jc.ErrorIsNil) defer state.SetBeforeHooks(c, s.State, func() { err := s.service.Destroy() c.Assert(err, jc.ErrorIsNil) }).Check() c.Assert(s.service.EnsureMinUnits(), gc.ErrorMatches, `cannot ensure minimum units for service "dummy-service": service is not alive`) }
func (s *VolumeStateSuite) TestDetachVolume(c *gc.C) { volume, machine := s.setupVolumeAttachment(c) assertDetach := func() { err := s.State.DetachVolume(machine.MachineTag(), volume.VolumeTag()) c.Assert(err, jc.ErrorIsNil) attachment := s.volumeAttachment(c, machine.MachineTag(), volume.VolumeTag()) c.Assert(attachment.Life(), gc.Equals, state.Dying) } defer state.SetBeforeHooks(c, s.State, assertDetach).Check() assertDetach() }
func (s *VolumeStateSuite) TestDestroyVolume(c *gc.C) { volume, _ := s.setupVolumeAttachment(c) assertDestroy := func() { err := s.State.DestroyVolume(volume.VolumeTag()) c.Assert(err, jc.ErrorIsNil) volume = s.volume(c, volume.VolumeTag()) c.Assert(volume.Life(), gc.Equals, state.Dying) } defer state.SetBeforeHooks(c, s.State, assertDestroy).Check() assertDestroy() }
func (s *MigrationSuite) TestCreateMigrationRace(c *gc.C) { defer state.SetBeforeHooks(c, s.State2, func() { mig, err := s.State2.CreateMigration(s.stdSpec) c.Assert(mig, gc.Not(gc.IsNil)) c.Assert(err, jc.ErrorIsNil) }).Check() mig, err := s.State2.CreateMigration(s.stdSpec) c.Check(mig, gc.IsNil) c.Check(err, gc.ErrorMatches, "failed to create migration: already in progress") }
func (s *CharmSuite) TestDestroyReferencedCharmRace(c *gc.C) { defer state.SetBeforeHooks(c, s.State, func() { s.Factory.MakeApplication(c, &factory.ApplicationParams{ Charm: s.charm, }) }).Check() err := s.charm.Destroy() c.Check(err, gc.ErrorMatches, "charm in use") }
func (s *FilesystemStateSuite) TestDestroyFilesystem(c *gc.C) { filesystem, _ := s.setupFilesystemAttachment(c, "rootfs") assertDestroy := func() { err := s.State.DestroyFilesystem(filesystem.FilesystemTag()) c.Assert(err, jc.ErrorIsNil) filesystem = s.filesystem(c, filesystem.FilesystemTag()) c.Assert(filesystem.Life(), gc.Equals, state.Dying) } defer state.SetBeforeHooks(c, s.State, assertDestroy).Check() assertDestroy() }
func (s *FilesystemStateSuite) TestEnsureMachineDeadRemoveFilesystemConcurrently(c *gc.C) { filesystem, machine := s.setupFilesystemAttachment(c, "rootfs") removeFilesystem := func() { s.obliterateFilesystem(c, filesystem.FilesystemTag()) } defer state.SetBeforeHooks(c, s.State, removeFilesystem).Check() // Removing a filesystem concurrently does not cause a transaction failure. err := machine.EnsureDead() c.Assert(err, jc.ErrorIsNil) }
func (s *FilesystemStateSuite) TestDetachFilesystem(c *gc.C) { filesystem, machine := s.setupFilesystemAttachment(c, "rootfs") assertDetach := func() { err := s.State.DetachFilesystem(machine.MachineTag(), filesystem.FilesystemTag()) c.Assert(err, jc.ErrorIsNil) attachment := s.filesystemAttachment(c, machine.MachineTag(), filesystem.FilesystemTag()) c.Assert(attachment.Life(), gc.Equals, state.Dying) } defer state.SetBeforeHooks(c, s.State, assertDetach).Check() assertDetach() }
func (s *linkLayerDevicesStateSuite) assertSetLinkLayerDevicesToContainerFailsWithBeforeHook(c *gc.C, beforeHook func(), expectedError string) { _, children := s.addParentBridgeDeviceWithContainerDevicesAsChildren(c, "br-eth1", "eth", 1) defer state.SetBeforeHooks(c, s.State, beforeHook).Check() newChildArgs := state.LinkLayerDeviceArgs{ Name: "eth1", Type: state.EthernetDevice, ParentName: children[0].ParentName(), } err := s.containerMachine.SetLinkLayerDevices(newChildArgs) c.Assert(err, gc.ErrorMatches, expectedError) }
func (s *VolumeStateSuite) TestRemoveVolumeAttachmentConcurrently(c *gc.C) { volume, machine := s.setupVolumeAttachment(c) err := s.State.DetachVolume(machine.MachineTag(), volume.VolumeTag()) c.Assert(err, jc.ErrorIsNil) remove := func() { err := s.State.RemoveVolumeAttachment(machine.MachineTag(), volume.VolumeTag()) c.Assert(err, jc.ErrorIsNil) assertMachineStorageRefs(c, s.State, machine.MachineTag()) } defer state.SetBeforeHooks(c, s.State, remove).Check() remove() }
func (s *FilesystemStateSuite) TestRemoveFilesystemAttachmentConcurrently(c *gc.C) { filesystem, machine := s.setupFilesystemAttachment(c, "rootfs") err := s.State.DetachFilesystem(machine.MachineTag(), filesystem.FilesystemTag()) c.Assert(err, jc.ErrorIsNil) remove := func() { err := s.State.RemoveFilesystemAttachment(machine.MachineTag(), filesystem.FilesystemTag()) c.Assert(err, jc.ErrorIsNil) assertMachineStorageRefs(c, s.State, machine.MachineTag()) } defer state.SetBeforeHooks(c, s.State, remove).Check() remove() }
func (s *MinUnitsSuite) TestMinUnitsRemoveBefore(c *gc.C) { err := s.service.SetMinUnits(41) c.Assert(err, jc.ErrorIsNil) defer state.SetBeforeHooks(c, s.State, func() { err := s.service.SetMinUnits(0) c.Assert(err, jc.ErrorIsNil) s.assertRevno(c, 0, mgo.ErrNotFound) }).Check() err = s.service.SetMinUnits(0) c.Assert(err, jc.ErrorIsNil) c.Assert(s.service.MinUnits(), gc.Equals, 0) }
func (s *ModelSuite) TestDestroyControllerAlreadyDyingRaceNoOp(c *gc.C) { env, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) // Simulate an model being destroyed by another client just before // the remove txn is called. defer state.SetBeforeHooks(c, s.State, func() { c.Assert(env.Destroy(), jc.ErrorIsNil) }).Check() c.Assert(env.Destroy(), jc.ErrorIsNil) }
func (s *EnvironSuite) TestDestroyControllerEnvironmentRace(c *gc.C) { // Simulate an environment being added just before the remove txn is // called. defer state.SetBeforeHooks(c, s.State, func() { blocker := s.Factory.MakeEnvironment(c, nil) err := blocker.Close() c.Check(err, jc.ErrorIsNil) }).Check() env, err := s.State.Environment() c.Assert(err, jc.ErrorIsNil) c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy environment: hosting 1 other environments") }
func (s *ModelSuite) TestDestroyControllerNonEmptyModelRace(c *gc.C) { // Simulate an empty model being added just before the // remove txn is called. defer state.SetBeforeHooks(c, s.State, func() { st := s.Factory.MakeModel(c, nil) defer st.Close() factory.NewFactory(st).MakeService(c, nil) }).Check() env, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy model: hosting 1 other models") }
func (s *ModelSuite) TestDestroyControllerEmptyModelRace(c *gc.C) { defer s.Factory.MakeModel(c, nil).Close() // Simulate an empty model being added just before the // remove txn is called. defer state.SetBeforeHooks(c, s.State, func() { s.Factory.MakeModel(c, nil).Close() }).Check() env, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(env.Destroy(), jc.ErrorIsNil) }
func (s *UpgradeSuite) TestAbortRace(c *gc.C) { info, err := s.State.EnsureUpgradeInfo(s.serverIdA, vers("1.2.3"), vers("2.3.4")) c.Assert(err, jc.ErrorIsNil) defer state.SetBeforeHooks(c, s.State, func() { err = info.Abort() c.Assert(err, jc.ErrorIsNil) }).Check() err = info.Abort() c.Assert(err, jc.ErrorIsNil) s.checkUpgradeInfoArchived(c, info, state.UpgradeAborted, 0) }
func (s *AnnotationsSuite) TestSetAnnotationsConcurrently(c *gc.C) { key := "conkey" first := "alpha" last := "omega" setAnnotations := func() { s.assertSetAnnotation(c, key, first) assertAnnotation(c, s.State, s.testEntity, key, first) } defer state.SetBeforeHooks(c, s.State, setAnnotations).Check() s.assertSetAnnotation(c, key, last) assertAnnotation(c, s.State, s.testEntity, key, last) }
func (s *ModelSuite) TestDestroyControllerModelRace(c *gc.C) { // Simulate an model being added just before the remove txn is // called. defer state.SetBeforeHooks(c, s.State, func() { blocker := s.Factory.MakeModel(c, nil) err := blocker.Close() c.Check(err, jc.ErrorIsNil) }).Check() env, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) c.Assert(env.Destroy(), gc.ErrorMatches, "failed to destroy model: hosting 1 other models") }
func (s *UnitSuite) TestSetCharmURLRetriesWithDeadUnit(c *gc.C) { preventUnitDestroyRemove(c, s.unit) defer state.SetBeforeHooks(c, s.State, func() { err := s.unit.Destroy() c.Assert(err, jc.ErrorIsNil) err = s.unit.EnsureDead() c.Assert(err, jc.ErrorIsNil) assertLife(c, s.unit, state.Dead) }).Check() err := s.unit.SetCharmURL(s.charm.URL()) c.Assert(err, gc.Equals, state.ErrDead) }
func (s *UnitSuite) TestRemoveUnitMachineRetryVoter(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.SetBeforeHooks(c, s.State, func() { s.setMachineVote(c, host.Id(), true) }, nil).Check() c.Assert(target.Destroy(), gc.IsNil) assertLife(c, host, state.Alive) }