github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/apiserver/client/destroy_test.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package client_test 5 6 import ( 7 "fmt" 8 9 "github.com/juju/errors" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 13 "github.com/juju/juju/apiserver/params" 14 "github.com/juju/juju/environs" 15 "github.com/juju/juju/instance" 16 "github.com/juju/juju/juju/testing" 17 "github.com/juju/juju/provider/dummy" 18 "github.com/juju/juju/state" 19 ) 20 21 type destroyEnvironmentSuite struct { 22 baseSuite 23 } 24 25 var _ = gc.Suite(&destroyEnvironmentSuite{}) 26 27 // setUpManual adds "manually provisioned" machines to state: 28 // one manager machine, and one non-manager. 29 func (s *destroyEnvironmentSuite) setUpManual(c *gc.C) (m0, m1 *state.Machine) { 30 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 31 c.Assert(err, jc.ErrorIsNil) 32 err = m0.SetProvisioned(instance.Id("manual:0"), "manual:0:fake_nonce", nil) 33 c.Assert(err, jc.ErrorIsNil) 34 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 35 c.Assert(err, jc.ErrorIsNil) 36 err = m1.SetProvisioned(instance.Id("manual:1"), "manual:1:fake_nonce", nil) 37 c.Assert(err, jc.ErrorIsNil) 38 return m0, m1 39 } 40 41 // setUpInstances adds machines to state backed by instances: 42 // one manager machine, one non-manager, and a container in the 43 // non-manager. 44 func (s *destroyEnvironmentSuite) setUpInstances(c *gc.C) (m0, m1, m2 *state.Machine) { 45 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 46 c.Assert(err, jc.ErrorIsNil) 47 inst, _ := testing.AssertStartInstance(c, s.Environ, m0.Id()) 48 err = m0.SetProvisioned(inst.Id(), "fake_nonce", nil) 49 c.Assert(err, jc.ErrorIsNil) 50 51 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 52 c.Assert(err, jc.ErrorIsNil) 53 inst, _ = testing.AssertStartInstance(c, s.Environ, m1.Id()) 54 err = m1.SetProvisioned(inst.Id(), "fake_nonce", nil) 55 c.Assert(err, jc.ErrorIsNil) 56 57 m2, err = s.State.AddMachineInsideMachine(state.MachineTemplate{ 58 Series: "precise", 59 Jobs: []state.MachineJob{state.JobHostUnits}, 60 }, m1.Id(), instance.LXC) 61 c.Assert(err, jc.ErrorIsNil) 62 err = m2.SetProvisioned("container0", "fake_nonce", nil) 63 c.Assert(err, jc.ErrorIsNil) 64 65 return m0, m1, m2 66 } 67 68 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentManual(c *gc.C) { 69 _, nonManager := s.setUpManual(c) 70 71 // If there are any non-manager manual machines in state, DestroyEnvironment will 72 // error. It will not set the Dying flag on the environment. 73 err := s.APIState.Client().DestroyEnvironment() 74 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("manually provisioned machines must first be destroyed with `juju destroy-machine %s`", nonManager.Id())) 75 env, err := s.State.Environment() 76 c.Assert(err, jc.ErrorIsNil) 77 c.Assert(env.Life(), gc.Equals, state.Alive) 78 79 // If we remove the non-manager machine, it should pass. 80 // Manager machines will remain. 81 err = nonManager.EnsureDead() 82 c.Assert(err, jc.ErrorIsNil) 83 err = nonManager.Remove() 84 c.Assert(err, jc.ErrorIsNil) 85 err = s.APIState.Client().DestroyEnvironment() 86 c.Assert(err, jc.ErrorIsNil) 87 err = env.Refresh() 88 c.Assert(err, jc.ErrorIsNil) 89 c.Assert(env.Life(), gc.Equals, state.Dying) 90 } 91 92 func (s *destroyEnvironmentSuite) TestDestroyEnvironment(c *gc.C) { 93 manager, nonManager, _ := s.setUpInstances(c) 94 managerId, _ := manager.InstanceId() 95 nonManagerId, _ := nonManager.InstanceId() 96 97 instances, err := s.Environ.Instances([]instance.Id{managerId, nonManagerId}) 98 c.Assert(err, jc.ErrorIsNil) 99 for _, inst := range instances { 100 c.Assert(inst, gc.NotNil) 101 } 102 103 services, err := s.State.AllServices() 104 c.Assert(err, jc.ErrorIsNil) 105 106 err = s.APIState.Client().DestroyEnvironment() 107 c.Assert(err, jc.ErrorIsNil) 108 109 // After DestroyEnvironment returns, we should have: 110 // - all non-manager instances stopped 111 instances, err = s.Environ.Instances([]instance.Id{managerId, nonManagerId}) 112 c.Assert(err, gc.Equals, environs.ErrPartialInstances) 113 c.Assert(instances[0], gc.NotNil) 114 c.Assert(instances[1], jc.ErrorIsNil) 115 // - all services in state are Dying or Dead (or removed altogether), 116 // after running the state Cleanups. 117 needsCleanup, err := s.State.NeedsCleanup() 118 c.Assert(err, jc.ErrorIsNil) 119 c.Assert(needsCleanup, jc.IsTrue) 120 err = s.State.Cleanup() 121 c.Assert(err, jc.ErrorIsNil) 122 for _, s := range services { 123 err = s.Refresh() 124 if err != nil { 125 c.Assert(err, jc.Satisfies, errors.IsNotFound) 126 } else { 127 c.Assert(s.Life(), gc.Not(gc.Equals), state.Alive) 128 } 129 } 130 // - environment is Dying 131 env, err := s.State.Environment() 132 c.Assert(err, jc.ErrorIsNil) 133 c.Assert(env.Life(), gc.Equals, state.Dying) 134 } 135 136 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentWithContainers(c *gc.C) { 137 ops := make(chan dummy.Operation, 500) 138 dummy.Listen(ops) 139 140 _, nonManager, _ := s.setUpInstances(c) 141 nonManagerId, _ := nonManager.InstanceId() 142 143 err := s.APIState.Client().DestroyEnvironment() 144 c.Assert(err, jc.ErrorIsNil) 145 for op := range ops { 146 if op, ok := op.(dummy.OpStopInstances); ok { 147 c.Assert(op.Ids, jc.SameContents, []instance.Id{nonManagerId}) 148 break 149 } 150 } 151 } 152 153 func (s *destroyEnvironmentSuite) TestBlockDestroyDestroyEnvironment(c *gc.C) { 154 // Setup environment 155 s.setUpInstances(c) 156 // lock environment: can't destroy locked environment 157 err := s.State.UpdateEnvironConfig(map[string]interface{}{"block-destroy-environment": true}, nil, nil) 158 c.Assert(err, jc.ErrorIsNil) 159 err = s.APIState.Client().DestroyEnvironment() 160 c.Assert(params.IsCodeOperationBlocked(err), jc.IsTrue) 161 } 162 163 func (s *destroyEnvironmentSuite) TestBlockRemoveDestroyEnvironment(c *gc.C) { 164 // Setup environment 165 s.setUpInstances(c) 166 // lock environment: can't destroy locked environment 167 err := s.State.UpdateEnvironConfig(map[string]interface{}{"block-remove-object": true}, nil, nil) 168 c.Assert(err, jc.ErrorIsNil) 169 err = s.APIState.Client().DestroyEnvironment() 170 c.Assert(params.IsCodeOperationBlocked(err), jc.IsTrue) 171 } 172 173 func (s *destroyEnvironmentSuite) TestBlockChangesDestroyEnvironment(c *gc.C) { 174 // Setup environment 175 s.setUpInstances(c) 176 // lock environment: can't destroy locked environment 177 err := s.State.UpdateEnvironConfig(map[string]interface{}{"block-all-changes": true}, nil, nil) 178 c.Assert(err, jc.ErrorIsNil) 179 err = s.APIState.Client().DestroyEnvironment() 180 c.Assert(params.IsCodeOperationBlocked(err), jc.IsTrue) 181 }