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 }