github.com/Pankov404/juju@v0.0.0-20150703034450-be266991dceb/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 "github.com/juju/names" 11 jc "github.com/juju/testing/checkers" 12 gc "gopkg.in/check.v1" 13 14 "github.com/juju/juju/apiserver/client" 15 "github.com/juju/juju/apiserver/common" 16 apiservertesting "github.com/juju/juju/apiserver/testing" 17 "github.com/juju/juju/environs" 18 "github.com/juju/juju/instance" 19 "github.com/juju/juju/juju/testing" 20 "github.com/juju/juju/provider/dummy" 21 "github.com/juju/juju/state" 22 jujutesting "github.com/juju/juju/testing" 23 "github.com/juju/juju/testing/factory" 24 ) 25 26 type destroyEnvironmentSuite struct { 27 baseSuite 28 } 29 30 var _ = gc.Suite(&destroyEnvironmentSuite{}) 31 32 // setUpManual adds "manually provisioned" machines to state: 33 // one manager machine, and one non-manager. 34 func (s *destroyEnvironmentSuite) setUpManual(c *gc.C) (m0, m1 *state.Machine) { 35 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 36 c.Assert(err, jc.ErrorIsNil) 37 err = m0.SetProvisioned(instance.Id("manual:0"), "manual:0:fake_nonce", nil) 38 c.Assert(err, jc.ErrorIsNil) 39 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 40 c.Assert(err, jc.ErrorIsNil) 41 err = m1.SetProvisioned(instance.Id("manual:1"), "manual:1:fake_nonce", nil) 42 c.Assert(err, jc.ErrorIsNil) 43 return m0, m1 44 } 45 46 // setUpInstances adds machines to state backed by instances: 47 // one manager machine, one non-manager, and a container in the 48 // non-manager. 49 func (s *destroyEnvironmentSuite) setUpInstances(c *gc.C) (m0, m1, m2 *state.Machine) { 50 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 51 c.Assert(err, jc.ErrorIsNil) 52 inst, _ := testing.AssertStartInstance(c, s.Environ, m0.Id()) 53 err = m0.SetProvisioned(inst.Id(), "fake_nonce", nil) 54 c.Assert(err, jc.ErrorIsNil) 55 56 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 57 c.Assert(err, jc.ErrorIsNil) 58 inst, _ = testing.AssertStartInstance(c, s.Environ, m1.Id()) 59 err = m1.SetProvisioned(inst.Id(), "fake_nonce", nil) 60 c.Assert(err, jc.ErrorIsNil) 61 62 m2, err = s.State.AddMachineInsideMachine(state.MachineTemplate{ 63 Series: "precise", 64 Jobs: []state.MachineJob{state.JobHostUnits}, 65 }, m1.Id(), instance.LXC) 66 c.Assert(err, jc.ErrorIsNil) 67 err = m2.SetProvisioned("container0", "fake_nonce", nil) 68 c.Assert(err, jc.ErrorIsNil) 69 70 return m0, m1, m2 71 } 72 73 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentManual(c *gc.C) { 74 _, nonManager := s.setUpManual(c) 75 76 // If there are any non-manager manual machines in state, DestroyEnvironment will 77 // error. It will not set the Dying flag on the environment. 78 err := s.APIState.Client().DestroyEnvironment() 79 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("failed to destroy environment: manually provisioned machines must first be destroyed with `juju destroy-machine %s`", nonManager.Id())) 80 env, err := s.State.Environment() 81 c.Assert(err, jc.ErrorIsNil) 82 c.Assert(env.Life(), gc.Equals, state.Alive) 83 84 // If we remove the non-manager machine, it should pass. 85 // Manager machines will remain. 86 err = nonManager.EnsureDead() 87 c.Assert(err, jc.ErrorIsNil) 88 err = nonManager.Remove() 89 c.Assert(err, jc.ErrorIsNil) 90 err = s.APIState.Client().DestroyEnvironment() 91 c.Assert(err, jc.ErrorIsNil) 92 err = env.Refresh() 93 c.Assert(err, jc.ErrorIsNil) 94 c.Assert(env.Life(), gc.Equals, state.Dying) 95 } 96 97 func (s *destroyEnvironmentSuite) TestDestroyEnvironment(c *gc.C) { 98 manager, nonManager, _ := s.setUpInstances(c) 99 managerId, _ := manager.InstanceId() 100 nonManagerId, _ := nonManager.InstanceId() 101 102 instances, err := s.Environ.Instances([]instance.Id{managerId, nonManagerId}) 103 c.Assert(err, jc.ErrorIsNil) 104 for _, inst := range instances { 105 c.Assert(inst, gc.NotNil) 106 } 107 108 services, err := s.State.AllServices() 109 c.Assert(err, jc.ErrorIsNil) 110 111 err = s.APIState.Client().DestroyEnvironment() 112 c.Assert(err, jc.ErrorIsNil) 113 114 // After DestroyEnvironment returns, we should have: 115 // - all non-manager instances stopped 116 instances, err = s.Environ.Instances([]instance.Id{managerId, nonManagerId}) 117 c.Assert(err, gc.Equals, environs.ErrPartialInstances) 118 c.Assert(instances[0], gc.NotNil) 119 c.Assert(instances[1], jc.ErrorIsNil) 120 // - all services in state are Dying or Dead (or removed altogether), 121 // after running the state Cleanups. 122 needsCleanup, err := s.State.NeedsCleanup() 123 c.Assert(err, jc.ErrorIsNil) 124 c.Assert(needsCleanup, jc.IsTrue) 125 err = s.State.Cleanup() 126 c.Assert(err, jc.ErrorIsNil) 127 for _, s := range services { 128 err = s.Refresh() 129 if err != nil { 130 c.Assert(err, jc.Satisfies, errors.IsNotFound) 131 } else { 132 c.Assert(s.Life(), gc.Not(gc.Equals), state.Alive) 133 } 134 } 135 // - environment is Dying 136 env, err := s.State.Environment() 137 c.Assert(err, jc.ErrorIsNil) 138 c.Assert(env.Life(), gc.Equals, state.Dying) 139 } 140 141 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentWithContainers(c *gc.C) { 142 ops := make(chan dummy.Operation, 500) 143 dummy.Listen(ops) 144 145 _, nonManager, _ := s.setUpInstances(c) 146 nonManagerId, _ := nonManager.InstanceId() 147 148 err := s.APIState.Client().DestroyEnvironment() 149 c.Assert(err, jc.ErrorIsNil) 150 for op := range ops { 151 if op, ok := op.(dummy.OpStopInstances); ok { 152 c.Assert(op.Ids, jc.SameContents, []instance.Id{nonManagerId}) 153 break 154 } 155 } 156 } 157 158 func (s *destroyEnvironmentSuite) TestBlockDestroyDestroyEnvironment(c *gc.C) { 159 // Setup environment 160 s.setUpInstances(c) 161 s.BlockDestroyEnvironment(c, "TestBlockDestroyDestroyEnvironment") 162 err := s.APIState.Client().DestroyEnvironment() 163 s.AssertBlocked(c, err, "TestBlockDestroyDestroyEnvironment") 164 } 165 166 func (s *destroyEnvironmentSuite) TestBlockRemoveDestroyEnvironment(c *gc.C) { 167 // Setup environment 168 s.setUpInstances(c) 169 s.BlockRemoveObject(c, "TestBlockRemoveDestroyEnvironment") 170 err := s.APIState.Client().DestroyEnvironment() 171 s.AssertBlocked(c, err, "TestBlockRemoveDestroyEnvironment") 172 } 173 174 func (s *destroyEnvironmentSuite) TestBlockChangesDestroyEnvironment(c *gc.C) { 175 // Setup environment 176 s.setUpInstances(c) 177 // lock environment: can't destroy locked environment 178 s.BlockAllChanges(c, "TestBlockChangesDestroyEnvironment") 179 err := s.APIState.Client().DestroyEnvironment() 180 s.AssertBlocked(c, err, "TestBlockChangesDestroyEnvironment") 181 } 182 183 type destroyTwoEnvironmentsSuite struct { 184 testing.JujuConnSuite 185 otherState *state.State 186 otherEnvOwner names.UserTag 187 otherEnvClient *client.Client 188 } 189 190 var _ = gc.Suite(&destroyTwoEnvironmentsSuite{}) 191 192 func (s *destroyTwoEnvironmentsSuite) SetUpTest(c *gc.C) { 193 s.JujuConnSuite.SetUpTest(c) 194 s.otherEnvOwner = names.NewUserTag("jess@dummy") 195 s.otherState = factory.NewFactory(s.State).MakeEnvironment(c, &factory.EnvParams{ 196 Owner: s.otherEnvOwner, 197 Prepare: true, 198 ConfigAttrs: jujutesting.Attrs{ 199 "state-server": false, 200 }, 201 }) 202 s.AddCleanup(func(*gc.C) { s.otherState.Close() }) 203 204 // get the client for the other environment 205 auth := apiservertesting.FakeAuthorizer{ 206 Tag: s.otherEnvOwner, 207 EnvironManager: false, 208 } 209 var err error 210 s.otherEnvClient, err = client.NewClient(s.otherState, common.NewResources(), auth) 211 c.Assert(err, jc.ErrorIsNil) 212 } 213 214 func (s *destroyTwoEnvironmentsSuite) TestCleanupEnvironDocs(c *gc.C) { 215 otherFactory := factory.NewFactory(s.otherState) 216 otherFactory.MakeMachine(c, nil) 217 m := otherFactory.MakeMachine(c, nil) 218 otherFactory.MakeMachineNested(c, m.Id(), nil) 219 220 err := s.otherEnvClient.DestroyEnvironment() 221 c.Assert(err, jc.ErrorIsNil) 222 223 _, err = s.otherState.Environment() 224 c.Assert(errors.IsNotFound(err), jc.IsTrue) 225 226 _, err = s.State.Environment() 227 c.Assert(err, jc.ErrorIsNil) 228 c.Assert(s.otherState.EnsureEnvironmentRemoved(), jc.ErrorIsNil) 229 } 230 231 func (s *destroyTwoEnvironmentsSuite) TestDestroyStateServerAfterNonStateServerIsDestroyed(c *gc.C) { 232 err := s.APIState.Client().DestroyEnvironment() 233 c.Assert(err, gc.ErrorMatches, "failed to destroy environment: state server environment cannot be destroyed before all other environments are destroyed") 234 err = s.otherEnvClient.DestroyEnvironment() 235 c.Assert(err, jc.ErrorIsNil) 236 err = s.APIState.Client().DestroyEnvironment() 237 c.Assert(err, jc.ErrorIsNil) 238 }