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  }