github.com/cloudbase/juju-core@v0.0.0-20140504232958-a7271ac7912f/cmd/juju/destroyenvironment_test.go (about)

     1  // Copyright 2012, 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package main
     5  
     6  import (
     7  	"bytes"
     8  
     9  	gc "launchpad.net/gocheck"
    10  
    11  	"launchpad.net/juju-core/cmd"
    12  	"launchpad.net/juju-core/environs"
    13  	"launchpad.net/juju-core/environs/configstore"
    14  	"launchpad.net/juju-core/errors"
    15  	"launchpad.net/juju-core/instance"
    16  	"launchpad.net/juju-core/juju/testing"
    17  	"launchpad.net/juju-core/provider/dummy"
    18  	coretesting "launchpad.net/juju-core/testing"
    19  	jc "launchpad.net/juju-core/testing/checkers"
    20  )
    21  
    22  type destroyEnvSuite struct {
    23  	testing.JujuConnSuite
    24  }
    25  
    26  var _ = gc.Suite(&destroyEnvSuite{})
    27  
    28  func (s *destroyEnvSuite) TestDestroyEnvironmentCommand(c *gc.C) {
    29  	// Prepare the environment so we can destroy it.
    30  	_, err := environs.PrepareFromName("dummyenv", nullContext(), s.ConfigStore)
    31  	c.Assert(err, gc.IsNil)
    32  
    33  	// check environment is mandatory
    34  	opc, errc := runCommand(nullContext(), new(DestroyEnvironmentCommand))
    35  	c.Check(<-errc, gc.Equals, NoEnvironmentError)
    36  
    37  	// normal destroy
    38  	opc, errc = runCommand(nullContext(), new(DestroyEnvironmentCommand), "dummyenv", "--yes")
    39  	c.Check(<-errc, gc.IsNil)
    40  	c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
    41  
    42  	// Verify that the environment information has been removed.
    43  	_, err = s.ConfigStore.ReadInfo("dummyenv")
    44  	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
    45  }
    46  
    47  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEFlag(c *gc.C) {
    48  	// Prepare the environment so we can destroy it.
    49  	_, err := environs.PrepareFromName("dummyenv", nullContext(), s.ConfigStore)
    50  	c.Assert(err, gc.IsNil)
    51  
    52  	// check that either environment or the flag is mandatory
    53  	opc, errc := runCommand(nullContext(), new(DestroyEnvironmentCommand))
    54  	c.Check(<-errc, gc.Equals, NoEnvironmentError)
    55  
    56  	// We don't allow them to supply both entries at the same time
    57  	opc, errc = runCommand(nullContext(), new(DestroyEnvironmentCommand), "-e", "dummyenv", "dummyenv", "--yes")
    58  	c.Check(<-errc, gc.Equals, DoubleEnvironmentError)
    59  	// We treat --environment the same way
    60  	opc, errc = runCommand(nullContext(), new(DestroyEnvironmentCommand), "--environment", "dummyenv", "dummyenv", "--yes")
    61  	c.Check(<-errc, gc.Equals, DoubleEnvironmentError)
    62  
    63  	// destroy using the -e flag
    64  	opc, errc = runCommand(nullContext(), new(DestroyEnvironmentCommand), "-e", "dummyenv", "--yes")
    65  	c.Check(<-errc, gc.IsNil)
    66  	c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
    67  
    68  	// Verify that the environment information has been removed.
    69  	_, err = s.ConfigStore.ReadInfo("dummyenv")
    70  	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
    71  }
    72  
    73  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) {
    74  	oldinfo, err := s.ConfigStore.ReadInfo("dummyenv")
    75  	c.Assert(err, gc.IsNil)
    76  	bootstrapConfig := oldinfo.BootstrapConfig()
    77  	apiEndpoint := oldinfo.APIEndpoint()
    78  	apiCredentials := oldinfo.APICredentials()
    79  	err = oldinfo.Destroy()
    80  	c.Assert(err, gc.IsNil)
    81  	newinfo, err := s.ConfigStore.CreateInfo("dummyenv")
    82  	c.Assert(err, gc.IsNil)
    83  
    84  	bootstrapConfig["broken"] = "Destroy"
    85  	newinfo.SetBootstrapConfig(bootstrapConfig)
    86  	newinfo.SetAPIEndpoint(apiEndpoint)
    87  	newinfo.SetAPICredentials(apiCredentials)
    88  	err = newinfo.Write()
    89  	c.Assert(err, gc.IsNil)
    90  
    91  	// Prepare the environment so we can destroy it.
    92  	_, err = environs.PrepareFromName("dummyenv", nullContext(), s.ConfigStore)
    93  	c.Assert(err, gc.IsNil)
    94  
    95  	// destroy with broken environment
    96  	opc, errc := runCommand(nullContext(), new(DestroyEnvironmentCommand), "dummyenv", "--yes")
    97  	op, ok := (<-opc).(dummy.OpDestroy)
    98  	c.Assert(ok, jc.IsTrue)
    99  	c.Assert(op.Error, gc.ErrorMatches, "dummy.Destroy is broken")
   100  	c.Check(<-errc, gc.Equals, op.Error)
   101  	c.Check(<-opc, gc.IsNil)
   102  }
   103  
   104  func (*destroyEnvSuite) TestDestroyEnvironmentCommandConfirmationFlag(c *gc.C) {
   105  	com := new(DestroyEnvironmentCommand)
   106  	c.Check(coretesting.InitCommand(com, []string{"dummyenv"}), gc.IsNil)
   107  	c.Check(com.assumeYes, gc.Equals, false)
   108  
   109  	com = new(DestroyEnvironmentCommand)
   110  	c.Check(coretesting.InitCommand(com, []string{"dummyenv", "-y"}), gc.IsNil)
   111  	c.Check(com.assumeYes, gc.Equals, true)
   112  
   113  	com = new(DestroyEnvironmentCommand)
   114  	c.Check(coretesting.InitCommand(com, []string{"dummyenv", "--yes"}), gc.IsNil)
   115  	c.Check(com.assumeYes, gc.Equals, true)
   116  }
   117  
   118  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) {
   119  	var stdin, stdout bytes.Buffer
   120  	ctx := cmd.DefaultContext()
   121  	ctx.Stdout = &stdout
   122  	ctx.Stdin = &stdin
   123  
   124  	// Prepare the environment so we can destroy it.
   125  	env, err := environs.PrepareFromName("dummyenv", nullContext(), s.ConfigStore)
   126  	c.Assert(err, gc.IsNil)
   127  
   128  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   129  
   130  	// Ensure confirmation is requested if "-y" is not specified.
   131  	stdin.WriteString("n")
   132  	opc, errc := runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   133  	c.Check(<-errc, gc.ErrorMatches, "Environment destruction aborted")
   134  	c.Check(<-opc, gc.IsNil)
   135  	c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*")
   136  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   137  
   138  	// EOF on stdin: equivalent to answering no.
   139  	stdin.Reset()
   140  	stdout.Reset()
   141  	opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   142  	c.Check(<-opc, gc.IsNil)
   143  	c.Check(<-errc, gc.ErrorMatches, "Environment destruction aborted")
   144  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   145  
   146  	// "--yes" passed: no confirmation request.
   147  	stdin.Reset()
   148  	stdout.Reset()
   149  	opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv", "--yes")
   150  	c.Check(<-errc, gc.IsNil)
   151  	c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
   152  	c.Check(stdout.String(), gc.Equals, "")
   153  	assertEnvironDestroyed(c, env, s.ConfigStore)
   154  
   155  	// Any of casing of "y" and "yes" will confirm.
   156  	for _, answer := range []string{"y", "Y", "yes", "YES"} {
   157  		// Prepare the environment so we can destroy it.
   158  		s.Reset(c)
   159  		env, err := environs.PrepareFromName("dummyenv", nullContext(), s.ConfigStore)
   160  		c.Assert(err, gc.IsNil)
   161  
   162  		stdin.Reset()
   163  		stdout.Reset()
   164  		stdin.WriteString(answer)
   165  		opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   166  		c.Check(<-errc, gc.IsNil)
   167  		c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
   168  		c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*")
   169  		assertEnvironDestroyed(c, env, s.ConfigStore)
   170  	}
   171  }
   172  
   173  func assertEnvironDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) {
   174  	_, err := store.ReadInfo(env.Name())
   175  	c.Assert(err, jc.Satisfies, errors.IsNotFoundError)
   176  
   177  	_, err = env.Instances([]instance.Id{"invalid"})
   178  	c.Assert(err, gc.ErrorMatches, "environment has been destroyed")
   179  }
   180  
   181  func assertEnvironNotDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) {
   182  	info, err := store.ReadInfo(env.Name())
   183  	c.Assert(err, gc.IsNil)
   184  	c.Assert(info.Initialized(), jc.IsTrue)
   185  
   186  	_, err = environs.NewFromName(env.Name(), store)
   187  	c.Assert(err, gc.IsNil)
   188  }