github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/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 "launchpad.net/gocheck" 12 13 "github.com/juju/juju/environs" 14 "github.com/juju/juju/instance" 15 "github.com/juju/juju/juju/testing" 16 "github.com/juju/juju/provider/dummy" 17 "github.com/juju/juju/state" 18 ) 19 20 type destroyEnvironmentSuite struct { 21 baseSuite 22 } 23 24 var _ = gc.Suite(&destroyEnvironmentSuite{}) 25 26 // setUpManual adds "manually provisioned" machines to state: 27 // one manager machine, and one non-manager. 28 func (s *destroyEnvironmentSuite) setUpManual(c *gc.C) (m0, m1 *state.Machine) { 29 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 30 c.Assert(err, gc.IsNil) 31 err = m0.SetProvisioned(instance.Id("manual:0"), "manual:0:fake_nonce", nil) 32 c.Assert(err, gc.IsNil) 33 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 34 c.Assert(err, gc.IsNil) 35 err = m1.SetProvisioned(instance.Id("manual:1"), "manual:1:fake_nonce", nil) 36 c.Assert(err, gc.IsNil) 37 return m0, m1 38 } 39 40 // setUpInstances adds machines to state backed by instances: 41 // one manager machine, one non-manager, and a container in the 42 // non-manager. 43 func (s *destroyEnvironmentSuite) setUpInstances(c *gc.C) (m0, m1, m2 *state.Machine) { 44 m0, err := s.State.AddMachine("precise", state.JobManageEnviron) 45 c.Assert(err, gc.IsNil) 46 inst, _ := testing.AssertStartInstance(c, s.APIConn.Environ, m0.Id()) 47 err = m0.SetProvisioned(inst.Id(), "fake_nonce", nil) 48 c.Assert(err, gc.IsNil) 49 50 m1, err = s.State.AddMachine("precise", state.JobHostUnits) 51 c.Assert(err, gc.IsNil) 52 inst, _ = testing.AssertStartInstance(c, s.APIConn.Environ, m1.Id()) 53 err = m1.SetProvisioned(inst.Id(), "fake_nonce", nil) 54 c.Assert(err, gc.IsNil) 55 56 m2, err = s.State.AddMachineInsideMachine(state.MachineTemplate{ 57 Series: "precise", 58 Jobs: []state.MachineJob{state.JobHostUnits}, 59 }, m1.Id(), instance.LXC) 60 c.Assert(err, gc.IsNil) 61 err = m2.SetProvisioned("container0", "fake_nonce", nil) 62 c.Assert(err, gc.IsNil) 63 64 return m0, m1, m2 65 } 66 67 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentManual(c *gc.C) { 68 _, nonManager := s.setUpManual(c) 69 70 // If there are any non-manager manual machines in state, DestroyEnvironment will 71 // error. It will not set the Dying flag on the environment. 72 err := s.APIState.Client().DestroyEnvironment() 73 c.Assert(err, gc.ErrorMatches, fmt.Sprintf("manually provisioned machines must first be destroyed with `juju destroy-machine %s`", nonManager.Id())) 74 env, err := s.State.Environment() 75 c.Assert(err, gc.IsNil) 76 c.Assert(env.Life(), gc.Equals, state.Alive) 77 78 // If we remove the non-manager machine, it should pass. 79 // Manager machines will remain. 80 err = nonManager.EnsureDead() 81 c.Assert(err, gc.IsNil) 82 err = nonManager.Remove() 83 c.Assert(err, gc.IsNil) 84 err = s.APIState.Client().DestroyEnvironment() 85 c.Assert(err, gc.IsNil) 86 err = env.Refresh() 87 c.Assert(err, gc.IsNil) 88 c.Assert(env.Life(), gc.Equals, state.Dying) 89 } 90 91 func (s *destroyEnvironmentSuite) TestDestroyEnvironment(c *gc.C) { 92 manager, nonManager, _ := s.setUpInstances(c) 93 managerId, _ := manager.InstanceId() 94 nonManagerId, _ := nonManager.InstanceId() 95 96 instances, err := s.APIConn.Environ.Instances([]instance.Id{managerId, nonManagerId}) 97 c.Assert(err, gc.IsNil) 98 for _, inst := range instances { 99 c.Assert(inst, gc.NotNil) 100 } 101 102 services, err := s.State.AllServices() 103 c.Assert(err, gc.IsNil) 104 105 err = s.APIState.Client().DestroyEnvironment() 106 c.Assert(err, gc.IsNil) 107 108 // After DestroyEnvironment returns, we should have: 109 // - all non-manager instances stopped 110 instances, err = s.APIConn.Environ.Instances([]instance.Id{managerId, nonManagerId}) 111 c.Assert(err, gc.Equals, environs.ErrPartialInstances) 112 c.Assert(instances[0], gc.NotNil) 113 c.Assert(instances[1], gc.IsNil) 114 // - all services in state are Dying or Dead (or removed altogether), 115 // after running the state Cleanups. 116 needsCleanup, err := s.State.NeedsCleanup() 117 c.Assert(err, gc.IsNil) 118 c.Assert(needsCleanup, jc.IsTrue) 119 err = s.State.Cleanup() 120 c.Assert(err, gc.IsNil) 121 for _, s := range services { 122 err = s.Refresh() 123 if err != nil { 124 c.Assert(err, jc.Satisfies, errors.IsNotFound) 125 } else { 126 c.Assert(s.Life(), gc.Not(gc.Equals), state.Alive) 127 } 128 } 129 // - environment is Dying 130 env, err := s.State.Environment() 131 c.Assert(err, gc.IsNil) 132 c.Assert(env.Life(), gc.Equals, state.Dying) 133 } 134 135 func (s *destroyEnvironmentSuite) TestDestroyEnvironmentWithContainers(c *gc.C) { 136 ops := make(chan dummy.Operation, 500) 137 dummy.Listen(ops) 138 139 _, nonManager, _ := s.setUpInstances(c) 140 nonManagerId, _ := nonManager.InstanceId() 141 142 err := s.APIState.Client().DestroyEnvironment() 143 c.Assert(err, gc.IsNil) 144 for op := range ops { 145 if op, ok := op.(dummy.OpStopInstances); ok { 146 c.Assert(op.Ids, jc.SameContents, []instance.Id{nonManagerId}) 147 break 148 } 149 } 150 }