github.com/mattyw/juju@v0.0.0-20140610034352-732aecd63861/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  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "launchpad.net/gocheck"
    12  
    13  	"github.com/juju/juju/cmd"
    14  	"github.com/juju/juju/environs"
    15  	"github.com/juju/juju/environs/configstore"
    16  	"github.com/juju/juju/instance"
    17  	"github.com/juju/juju/juju/testing"
    18  	"github.com/juju/juju/provider/dummy"
    19  	coretesting "github.com/juju/juju/testing"
    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(c), s.ConfigStore)
    31  	c.Assert(err, gc.IsNil)
    32  
    33  	// check environment is mandatory
    34  	opc, errc := runCommand(nullContext(c), new(DestroyEnvironmentCommand))
    35  	c.Check(<-errc, gc.Equals, NoEnvironmentError)
    36  
    37  	// normal destroy
    38  	opc, errc = runCommand(nullContext(c), 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.IsNotFound)
    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(c), s.ConfigStore)
    50  	c.Assert(err, gc.IsNil)
    51  
    52  	// check that either environment or the flag is mandatory
    53  	opc, errc := runCommand(nullContext(c), 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(c), 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(c), 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(c), 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.IsNotFound)
    71  }
    72  
    73  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandEmptyJenv(c *gc.C) {
    74  	_, err := s.ConfigStore.CreateInfo("emptyenv")
    75  	c.Assert(err, gc.IsNil)
    76  
    77  	context, err := coretesting.RunCommand(c, new(DestroyEnvironmentCommand), "-e", "emptyenv")
    78  	c.Assert(err, gc.IsNil)
    79  
    80  	c.Assert(coretesting.Stderr(context), gc.Equals, "removing empty environment file\n")
    81  }
    82  
    83  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandBroken(c *gc.C) {
    84  	oldinfo, err := s.ConfigStore.ReadInfo("dummyenv")
    85  	c.Assert(err, gc.IsNil)
    86  	bootstrapConfig := oldinfo.BootstrapConfig()
    87  	apiEndpoint := oldinfo.APIEndpoint()
    88  	apiCredentials := oldinfo.APICredentials()
    89  	err = oldinfo.Destroy()
    90  	c.Assert(err, gc.IsNil)
    91  	newinfo, err := s.ConfigStore.CreateInfo("dummyenv")
    92  	c.Assert(err, gc.IsNil)
    93  
    94  	bootstrapConfig["broken"] = "Destroy"
    95  	newinfo.SetBootstrapConfig(bootstrapConfig)
    96  	newinfo.SetAPIEndpoint(apiEndpoint)
    97  	newinfo.SetAPICredentials(apiCredentials)
    98  	err = newinfo.Write()
    99  	c.Assert(err, gc.IsNil)
   100  
   101  	// Prepare the environment so we can destroy it.
   102  	_, err = environs.PrepareFromName("dummyenv", nullContext(c), s.ConfigStore)
   103  	c.Assert(err, gc.IsNil)
   104  
   105  	// destroy with broken environment
   106  	opc, errc := runCommand(nullContext(c), new(DestroyEnvironmentCommand), "dummyenv", "--yes")
   107  	op, ok := (<-opc).(dummy.OpDestroy)
   108  	c.Assert(ok, jc.IsTrue)
   109  	c.Assert(op.Error, gc.ErrorMatches, "dummy.Destroy is broken")
   110  	c.Check(<-errc, gc.Equals, op.Error)
   111  	c.Check(<-opc, gc.IsNil)
   112  }
   113  
   114  func (*destroyEnvSuite) TestDestroyEnvironmentCommandConfirmationFlag(c *gc.C) {
   115  	com := new(DestroyEnvironmentCommand)
   116  	c.Check(coretesting.InitCommand(com, []string{"dummyenv"}), gc.IsNil)
   117  	c.Check(com.assumeYes, gc.Equals, false)
   118  
   119  	com = new(DestroyEnvironmentCommand)
   120  	c.Check(coretesting.InitCommand(com, []string{"dummyenv", "-y"}), gc.IsNil)
   121  	c.Check(com.assumeYes, gc.Equals, true)
   122  
   123  	com = new(DestroyEnvironmentCommand)
   124  	c.Check(coretesting.InitCommand(com, []string{"dummyenv", "--yes"}), gc.IsNil)
   125  	c.Check(com.assumeYes, gc.Equals, true)
   126  }
   127  
   128  func (s *destroyEnvSuite) TestDestroyEnvironmentCommandConfirmation(c *gc.C) {
   129  	var stdin, stdout bytes.Buffer
   130  	ctx, err := cmd.DefaultContext()
   131  	c.Assert(err, gc.IsNil)
   132  	ctx.Stdout = &stdout
   133  	ctx.Stdin = &stdin
   134  
   135  	// Prepare the environment so we can destroy it.
   136  	env, err := environs.PrepareFromName("dummyenv", nullContext(c), s.ConfigStore)
   137  	c.Assert(err, gc.IsNil)
   138  
   139  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   140  
   141  	// Ensure confirmation is requested if "-y" is not specified.
   142  	stdin.WriteString("n")
   143  	opc, errc := runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   144  	c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted")
   145  	c.Check(<-opc, gc.IsNil)
   146  	c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*")
   147  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   148  
   149  	// EOF on stdin: equivalent to answering no.
   150  	stdin.Reset()
   151  	stdout.Reset()
   152  	opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   153  	c.Check(<-opc, gc.IsNil)
   154  	c.Check(<-errc, gc.ErrorMatches, "environment destruction aborted")
   155  	assertEnvironNotDestroyed(c, env, s.ConfigStore)
   156  
   157  	// "--yes" passed: no confirmation request.
   158  	stdin.Reset()
   159  	stdout.Reset()
   160  	opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv", "--yes")
   161  	c.Check(<-errc, gc.IsNil)
   162  	c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
   163  	c.Check(stdout.String(), gc.Equals, "")
   164  	assertEnvironDestroyed(c, env, s.ConfigStore)
   165  
   166  	// Any of casing of "y" and "yes" will confirm.
   167  	for _, answer := range []string{"y", "Y", "yes", "YES"} {
   168  		// Prepare the environment so we can destroy it.
   169  		s.Reset(c)
   170  		env, err := environs.PrepareFromName("dummyenv", nullContext(c), s.ConfigStore)
   171  		c.Assert(err, gc.IsNil)
   172  
   173  		stdin.Reset()
   174  		stdout.Reset()
   175  		stdin.WriteString(answer)
   176  		opc, errc = runCommand(ctx, new(DestroyEnvironmentCommand), "dummyenv")
   177  		c.Check(<-errc, gc.IsNil)
   178  		c.Check((<-opc).(dummy.OpDestroy).Env, gc.Equals, "dummyenv")
   179  		c.Check(stdout.String(), gc.Matches, "WARNING!.*dummyenv.*\\(type: dummy\\)(.|\n)*")
   180  		assertEnvironDestroyed(c, env, s.ConfigStore)
   181  	}
   182  }
   183  
   184  func assertEnvironDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) {
   185  	_, err := store.ReadInfo(env.Name())
   186  	c.Assert(err, jc.Satisfies, errors.IsNotFound)
   187  
   188  	_, err = env.Instances([]instance.Id{"invalid"})
   189  	c.Assert(err, gc.ErrorMatches, "environment has been destroyed")
   190  }
   191  
   192  func assertEnvironNotDestroyed(c *gc.C, env environs.Environ, store configstore.Storage) {
   193  	info, err := store.ReadInfo(env.Name())
   194  	c.Assert(err, gc.IsNil)
   195  	c.Assert(info.Initialized(), jc.IsTrue)
   196  
   197  	_, err = environs.NewFromName(env.Name(), store)
   198  	c.Assert(err, gc.IsNil)
   199  }